循环时是否会并行执行 await 调用?
Will await calls be performed in parallel when looped over?
假设我们看起来像这样:
documents.forEach(url=>{
await fetch(url).
then(
document=>
console.log(document);
}
这是并行加载所有文档,还是串行加载文档?
换句话说,我们可以将 fetch
promise 推入一个数组,然后在该数组上调用 Promise.all
,这将并行执行所有 promise。
IIUC 除了 Promise.all
会在 fetch
请求的第一次失败时失败之外,实际上没有区别。
如果回调函数声明为async
,则可以使用await
:
documents.forEach(async url => {
await fetch(url).then(console.log);
}
执行顺序如下:
- 执行
forEach
方法
- 这包括为每个
url
调用回调,一个接一个
- 回调的一次执行将调用
fetch
,它会立即启动 HTTP 请求和 returns 并承诺。在后台,非 JavaScript、较低级别 API 轮询 HTTP 响应进入。只有后台部分与此处描述的步骤并行发生。
- 执行
then
方法并注册传递给它的回调。 then
方法立即returns一个promise
await
开始:回调函数的执行上下文被保存并退出,返回此代码忽略的承诺。
- 下一次迭代发生,从步骤 3 开始重复。
forEach
方法结束。在这个阶段有几个非JavaScript 线程轮询 HTTP 响应,并且有几个 JS 执行上下文等待稍后执行。
- 以某种不可预知的顺序(取决于给出响应的服务器的响应时间),
fetch
API 解析它已返回的承诺,并在 Promise Job 中放入一条消息队列说明。
- JavaScript 事件循环检测到事件并继续执行在步骤 4 中注册的回调(
then
回调),输出到控制台。 then
方法返回的承诺已解决,这会将新消息放入承诺作业队列中。
- 从队列中拉取消息,这将恢复
forEach
回调的相应执行上下文。在 await
之后继续执行,并且由于没有更多要执行的内容,所以在步骤 5 中返回的承诺已解决(但没有人听)
- JavaScript 监视事件队列以进行更多此类工作,并将在某个时候重复第 8 步。
这里没有JavaScript代码与JavaScript并行执行,但是fetch
API依赖非JavaScript代码,达到"down" 到操作系统函数中,do 运行 与 JavaScript 代码(和其他 OS 函数)并行。
另请注意,代码与此非async/await
变体非常相似:
documents.forEach(url =>
fetch(url).then(console.log)
);
...因为这个回调 也是 returns 一个承诺。除了 "saving execution context" 部分没有发生在这里,执行计划非常相似。
假设我们看起来像这样:
documents.forEach(url=>{
await fetch(url).
then(
document=>
console.log(document);
}
这是并行加载所有文档,还是串行加载文档?
换句话说,我们可以将 fetch
promise 推入一个数组,然后在该数组上调用 Promise.all
,这将并行执行所有 promise。
IIUC 除了 Promise.all
会在 fetch
请求的第一次失败时失败之外,实际上没有区别。
如果回调函数声明为async
,则可以使用await
:
documents.forEach(async url => {
await fetch(url).then(console.log);
}
执行顺序如下:
- 执行
forEach
方法 - 这包括为每个
url
调用回调,一个接一个 - 回调的一次执行将调用
fetch
,它会立即启动 HTTP 请求和 returns 并承诺。在后台,非 JavaScript、较低级别 API 轮询 HTTP 响应进入。只有后台部分与此处描述的步骤并行发生。 - 执行
then
方法并注册传递给它的回调。then
方法立即returns一个promise await
开始:回调函数的执行上下文被保存并退出,返回此代码忽略的承诺。- 下一次迭代发生,从步骤 3 开始重复。
forEach
方法结束。在这个阶段有几个非JavaScript 线程轮询 HTTP 响应,并且有几个 JS 执行上下文等待稍后执行。- 以某种不可预知的顺序(取决于给出响应的服务器的响应时间),
fetch
API 解析它已返回的承诺,并在 Promise Job 中放入一条消息队列说明。 - JavaScript 事件循环检测到事件并继续执行在步骤 4 中注册的回调(
then
回调),输出到控制台。then
方法返回的承诺已解决,这会将新消息放入承诺作业队列中。 - 从队列中拉取消息,这将恢复
forEach
回调的相应执行上下文。在await
之后继续执行,并且由于没有更多要执行的内容,所以在步骤 5 中返回的承诺已解决(但没有人听) - JavaScript 监视事件队列以进行更多此类工作,并将在某个时候重复第 8 步。
这里没有JavaScript代码与JavaScript并行执行,但是fetch
API依赖非JavaScript代码,达到"down" 到操作系统函数中,do 运行 与 JavaScript 代码(和其他 OS 函数)并行。
另请注意,代码与此非async/await
变体非常相似:
documents.forEach(url =>
fetch(url).then(console.log)
);
...因为这个回调 也是 returns 一个承诺。除了 "saving execution context" 部分没有发生在这里,执行计划非常相似。