循环时,等待呼叫是否会并行执行?

假设我们看起来像这样:

documents.forEach(url=>{
     await fetch(url).
     then(
        document=>
        console.log(document);
}

这会并行加载所有文档,还是会串行加载文档?

换句话说,我们可以将fetch承诺发送到一个数组中,然后在该数组上调用Promise.all,它将并行执行所有承诺。

IIUC确实没有什么区别,除了Promise.all在第一次fetch请求失败时将失败。

lpf3288547 回答:循环时,等待呼叫是否会并行执行?

提供的回调函数声明为async,则可以使用await

documents.forEach(async url => {
     await fetch(url).then(console.log);
}

执行顺序如下:

  1. 执行forEach方法。
  2. 这包括为每个url调用一次回调,这是一个接一个的
  3. 对回调的一次执行将调用fetch,它会启动HTTP请求并立即返回承诺。在后台,非JavaScript的较低级API轮询是否有HTTP响应进入。只有该后台部分与此处描述的步骤并行发生。
  4. 执行then方法,并注册传递给它的回调。 then方法立即返回一个诺言
  5. await插入:回调函数的执行上下文已保存并退出,并返回此代码忽略的promise。
  6. 发生下一次迭代,从第3步开始重复。
  7. forEach方法结束。在此阶段,有多个非JavaScript线程轮询HTTP响应,并且有多个JS执行上下文正在等待以后执行。
  8. fetch API以某种不可预测的顺序(取决于给出响应的服务器的响应时间)来解析其已返回的承诺,并在Promise Job Queue中放入一条消息来表明这一点。 / li>
  9. JavaScript事件循环检测到该事件,并继续执行在步骤4中注册的回调(then回调),并输出到控制台。由then方法返回的promise已解决,这将在Promise Job Queue中放入新消息。
  10. 该消息从队列中拉出,这将恢复forEach回调的相应执行上下文。在await之后继续执行,由于没有更多要执行的内容,因此解决了第5步中返回的诺言(但没人听)
  11. JavaScript监视事件队列以进行更多此类工作,并将在某些时候在步骤8重复。

此处没有JavaScript代码与JavaScript并行执行,但是fetch API依赖于非JavaScript代码,可以“向下”进入操作系统功能,而 do 与JavaScript代码(和其他OS功能)。

还要注意,代码与以下非async/await变体非常相似:

documents.forEach(url =>
     fetch(url).then(console.log)
);

...因为此回调返回了一个promise。除了“保存执行上下文”部分(此处未进行)之外,执行计划非常相似。

本文链接:https://www.f2er.com/2975341.html

大家都在问