异步并发调用

本文最后更新于: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

异步并发调用
https://blog.rxliuli.com/p/f263e3042824498597a02b35a7ed4dcd/
作者
rxliuli
发布于
2020年7月16日
许可协议