需求概述

遍历给定数据(此处为数组),依次执行针对数据项的异步任务。

【【所以机翻的文件名真的有意义么「- -」】】

代码

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
(() => {
const items = [
{
"code": 1,
"name": "A",
"children": [
{
"code": 101,
"name": "A-a"
},
{
"code": 102,
"name": "A-b"
}
]
},
{
"code": 2,
"name": "B",
"children": [
{
"code": 201,
"name": "B-a"
},
{
"code": 102,
"name": "B-b"
}
]
}
];

// 执行队列,第二个参数控制是否循环执行
async function runPromiseByQueue(listPromises, loop = 0) {
// console.log(listPromises);
for (let itemPromise of listPromises) {
await itemPromise();
}
if (loop) {
await runPromiseByQueue(listPromises, loop);
}
}

// 返回项为一个函数,该函数调用时会建立一个 Promise 对象并立即执行
// 当内部调用 solve() 时表示该异步项执行结束
const createPromise = (item, level = 0) => () =>
new Promise((solve) => {
setTimeout(async () => {
console.log(level, item.name);
if (item.hasOwnProperty("children")) {
level++;
const curQueue = createQueue(item.children, level);
await runPromiseByQueue(curQueue);
}
solve();
}, 1370);
});

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

// // 理论上也可以像下边这样延迟
// const createPromise = (item, level = 0) => () =>
// new Promise((solve) => {
// (async () => {
// await sleep(1370);
// console.log(level, item.name);
// if (item.hasOwnProperty("children")) {
// level++;
// const curQueue = createQueue(item.children, level);
// await runPromiseByQueue(curQueue);
// }
// solve();
// })();
// })

// 构造任务队列
const createQueue = (arr, level = 0) => {
return arr.map((item) => {
return createPromise(item, level);
});
};

// 执行
const curQueue = createQueue(items);

runPromiseByQueue(curQueue);

// // 循环执行
// runPromiseByQueue(curQueue, 1);
})();