-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpromisAllFetch.js
49 lines (45 loc) · 1.46 KB
/
promisAllFetch.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// 任务
const timeout = i => {
new Promise(reslove => {
setTimeout(() => reslove(i), i)
console.log("这是哪个异步任务", i)
})
}
// 模拟四个任务[1000, 2000, 3000, 4000]
asyncPool(2, [1000, 2000, 3000, 4000], timeout).then(result => {
// console.log(result)
})
/**
poolLimit 限制并发数
iteratorFn 回调函数
*/
function asyncPool(poolLimit, tasks, iteratorFn) {
let i = 0;
const ret = [];
const executing = [];
const enqueue = function () {
// 边界处理
if (i === tasks.length) {
return Promise.resolve();
}
// 每调一次enqueue,初始化一个promise
const currTask = tasks[i++];
const p = Promise.resolve().then(() => iteratorFn(currTask, tasks));
// 放入promises数组
ret.push(p);
// promise执行完毕,从executing数组中删除
const e = p.then(() => {
executing.splice(executing.indexOf(e), 1)
});
// 插入executing数字,表示正在执行的promise
executing.push(e);
// 使用Promise.rece,每当executing数组中promise数量低于poolLimit,就实例化新的promise并执行
let r = Promise.resolve();
if (executing.length >= poolLimit) {
r = Promise.race(executing);
}
// 递归,直到遍历完array
return r.then(() => enqueue());
};
return enqueue().then(() => Promise.all(ret));
}