面试题继发执行 : 1s后执行10,等1s后输出20,再等1s后输出30 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<script type="text/javascript">
function Pro(val) {
return new Promise((resolve, reject) => {
setTimeout(function() {
resolve(val)
}, 1000)
})
}
async function log(arrs) {
for(const item of arrs) {
var response = await Pro(item);
console.log(response);
}
}
log([10, 20, 30])
</script>
问题:给定一个 URL 数组,如何实现接口的继发和并发?
async 继发实现:
继发一
1 | async function loadData() { |
继发二
1 | async function loadData(urls) { |
async 并发实现:
并发一
1 | async function loadData() { |
并发二
1 | async function loadData(urls) { |
并发三[for await of]
for of方法能够遍历具有Symbol.iterator接口的同步迭代器数据,但是不能遍历异步迭代器。
ES9新增的for await of可以用来遍历具有Symbol.asyncIterator方法的数据结构,也就是异步迭代器,且会等待前一个成员的状态改变后才会遍历到下一个成员,相当于async函数内部的await。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// for of遍历
function Gen (time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(time)
}, time)
})
}
async function test () {
let arr = [Gen(2000), Gen(100), Gen(3000)] // 并发执行
for (let item of arr) {
console.log(Date.now(), item.then(console.log))
}
}
test()
// 1576391094972 Promise {<pending>}
// 1576391094973 Promise {<pending>}
// 1576391094973 Promise {<pending>}
// Promise {<resolved>: undefined}
// 100
// 2000
// 3000
上述代码证实了for of方法不能遍历异步迭代器,得到的结果并不是我们所期待的,于是for await of就粉墨登场啦!
1 | function Gen (time) { |
for await of
和 并发二 的有异曲同工之妙!!!1
2
3
4
5
6
7
8
9
10
// 按次序输出
for await (let item of arr) {
console.log(Date.now(), item) // 按次序输出
}
// 按次序输出
for (const textPromise of textPromises) {
console.log(await textPromise); // 按次序输出
}