Open lbwa opened 6 years ago
const jsonPromises = urls.map(async url => {
const response = await fetch(url);
return response.json();
})
在以上代码中,值得注意的是数组的 map
方法不在乎传入的参数是异步还是同步的函数。示例代码中的 map
方法仅仅把异步函数当作一个 返回 Promise 对象的函数 来对待。那么它并不会等到异步函数完全执行完成就会继续调用下一个异步函数。
究其原因就是 map
将异步函数看作一个返回 Promise 对象的函数,因为于异步函数体内何时 resolved
,外部是无法感知的。map
就仅仅会调用完成异步函数,就表示调用 '完成'
,那么它就会继续调用下一个异步函数。特别地,异步函数体内的 await
语句总是通过在微任务中调用来实现非阻塞流程。
// client.js
[1,2,3,4].map(async () => {
return await fetch('http://localhost:3000').then(res => res.json())
})
// server.js
const http = require('http')
http.createServer(function (req, res) {
console.log('req.url :', req.url)
res.writeHead(200, {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
})
// 五秒后响应
setTimeout(() => {
res.end(JSON.stringify({
msg: Date.now()
}))
}, 5000)
}).listen(3000)
当 client
发起请求时,server
端中返回的响应数据包含响应时间。若客户端中的异步函数是串行请求,那么 client
端接受到的响应数据中各自的时间的间隔至少是 5 秒,而结果显示他们之间几乎是同时收到响应数据,也就表明 server
端是同时接受到 client
端发起的 4 个请求,那么也就表明 client
端的 map
函数仅仅将参数中的异步函数当作一个返回 Promise 对象的普通函数来对待,map
函数不会等到异步函数完全执行就会调用下一个异步函数。
async 函数中的并行执行
在
async
函数中,仅当存在await
关键词的地方表示需要等待计算结果。那么存在互不依赖的操作时,不要错失并行执行的机会。Notice: 以下示例代码中的
wait()
方法表示异步操作。因为在async
函数中的同步操作与有没有await
不对整个async
函数内部执行顺序造成影响。因为函数体中的同步操作将按照常规单线程event loop
执行,await
后如果是非Promise
对象,那么await
将 直接 返回一个包含该同步操作的Promise
对象。以上代码中,
op0
和op1
的运行关系是同步执行,即只有等到op0
执行完成后才会执行op1
。以上代码
op0
和op1
将并行执行。同时还存在以下一种并行执行的写法:
Reference
Async function(Google Developers)
ECMAScript 6 入门