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