首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ECMAScript-2017中的“异步函数”在多大程度上是异步的?

ECMAScript-2017中的“异步函数”在多大程度上是异步的?
EN

Stack Overflow用户
提问于 2017-07-23 08:33:04
回答 1查看 67关注 0票数 2

大约一个月前刚刚定稿的ECMAScript-2017引入了“异步函数”作为一个新特性。为了了解它们是如何‘异步’的,我在Chrome中进行了一个测试:

代码语言:javascript
复制
async function af1(){
   for (let i=0; i<300; i++)
      await (new Promise(
                (resolve,reject)=>{
                   for (let j=0; j<=4; j++) console.log(j);resolve();}))
            .then(()=>{for (let j=100; j<=400; j+=100) console.log(j);});;
}

async function af2(){
   for (let i=0; i<300; i++)
      await (new Promise(
                (resolve,reject)=>{
                   for (let j=5; j<=9; j++) console.log(j);resolve();}))
            .then(()=>{for (let j=500; j<=900; j+=100)  console.log(j);});
}
af1();
console.log(300);
af2();
console.log(400);
// 0 1 2 3 4 300 5 6 7 8 9 400 100 200 300 400 500 600 700 800 900
// 0 1 2 3 4 5 6 7 8 9 100 200 300 400 500 600 700 800 900
// 0 1 2 3 4 5 6 7 8 9 100 200 300 400 500 600 700 800 900
// 0 1 2 3 4 5 6 7 8 9 100 200 300 400 500 600 700 800 900
// 0 1 2 3 4 5 6 7 8 9 100 200 300 400 500 600 700 800 900
// 0 1 2 3 4 5 6 7 8 9 100 200 300 400 500 600 700 800 900
// ......

实际上我在期待一个更随机的序列。

现在,我是否可以有把握地说,每个代码块表示一个承诺或其当时()回调中的一个是原子的,也就是说,代码块中的代码的执行不会被同一程序中的代码的另一部分中断?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-23 08:50:50

编写异步代码并不意味着输出将是随机的。当承诺立即得到解决(而不是依赖于某个不受控制的外部事件)时,事件的顺序实际上是可预测的:

在允诺构造函数回调函数中执行的所有内容都将在创建承诺时执行,即在继续使用new Promise()后面的代码之前,它将同步运行。

然后执行其余的同步代码,直到调用堆栈为空。

然后,作为附加到当前任务的微任务的一部分,按照以前执行then方法的顺序执行异步then回调。

await关键字还将影响执行顺序:它们发生的async函数将“停止”,让调用代码同步地继续,就好像async函数已经执行了return (它返回一个承诺)。一旦解决了提供给await的承诺,async函数将异步恢复其状态(在当前执行的代码运行到调用堆栈为空),并继续作为微任务的一部分。这与then回调的时间相同。

这解释了你的输出。不涉及随机性。

示例

例如,在第一行输出的末尾,900,什么信号表明执行返回到af1()

在输出900时,队列中有两个挂起的微任务:

1) then回调在af1中已经完成执行,返回undefined的值(因为它没有return),这表示await正在等待的承诺值。这对于异步处理是挂起的,而当前代码在调用堆栈为空之前仍在运行。

2) then回调在af2中也完成了执行:相同的原则。

由于(1)是microtask队列中的第一个,这是在900输出之后发生的,并且没有更多的同步代码要执行(调用堆栈为空):

JavaScript引擎读取微任务队列并接受微任务来处理第一个await:函数状态被恢复,包括它的循环状态,并且循环继续。这意味着承诺构造函数回调将同步执行,从而产生输出第二行中的第一个值。...etc。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45263085

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档