异步并发调用

本文最后更新于:2020年12月13日 早上

问题

你觉得下面这段代码会怎么打印?这里使用异步模拟了 10 个 thread,然后从 generator 里面迭代取值

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
const sleep = (sec) =>
new Promise((res, rej) => {
setTimeout(res, sec * 1000);
});
const group = (arr, kFn) =>
arr.reduce((res, item) => {
const i = kFn(item);
res[i] = (res[i] || 0) + 1;
return res;
}, {});

const fibGenerator = function* (n) {
let [a, b] = [0, 1];
for (let i = 0; i < n; i++) {
yield a;
[a, b] = [b, a + b];
}
};
const fibIterator = fibGenerator(100);
// 开十个 thread
const idxArr = Array(10)
.fill(0)
.map((_, i) => i);
const arr = [];
Promise.all(
idxArr.map(async (i) => {
for (const num of fibIterator) {
arr.push([i, num]);
// 如果改成 await sleep(0) 呢?
await sleep(Math.random());
}
})
).then(() => {
console.log(
arr.length,
arr,
group(arr, ([i]) => i)
);
});

答案

主要考察并发异步和迭代器的知识

修改前

  • 100 个,因为 generator 只能迭代 100 次
  • 没什么规律的数组,因为队列在第一次之后追加的 idx 顺序是不确定的,会是 1,2,3…9 然后后面线程就不能确定了
  • 每个线程运行次数至少为 1

修改后

  • 同上
  • 确定的数组,线程是 0,1,2…9 的循环,对应的值则是从 0-99 对应的斐波那契数列递增
  • 确定的对象,每个线程运行次数均为 10

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!