Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript ECMAScript-2017中“异步函数”的异步程度如何?_Javascript_Asynchronous_Concurrency_Async Await - Fatal编程技术网

Javascript ECMAScript-2017中“异步函数”的异步程度如何?

Javascript ECMAScript-2017中“异步函数”的异步程度如何?,javascript,asynchronous,concurrency,async-await,Javascript,Asynchronous,Concurrency,Async Await,大约一个月前刚刚定稿的ECMAScript-2017引入了一项新功能。为了了解它们的“异步”程度,我在Chrome中进行了一项测试: 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);re

大约一个月前刚刚定稿的ECMAScript-2017引入了一项新功能。为了了解它们的“异步”程度,我在Chrome中进行了一项测试:

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
// ......
事实上,我期待一个更随机的序列


现在,我可以有把握地说,表示承诺或其回调的每个代码块都是原子的,因为块内代码的执行不会被同一程序内的另一部分代码打断?

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

Promise构造函数回调函数中执行的所有操作都将在创建Promise时执行,即在继续执行新Promise之后的代码之前,它将同步运行

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

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

wait关键字还将影响执行顺序:它们出现的异步函数将停止,让调用代码同步继续,就好像异步函数执行了一个返回,它返回一个承诺一样。一旦为wait提供的承诺得到解决,异步函数将在当前执行代码运行后异步恢复其状态,直到调用堆栈为空,并作为微任务的一部分继续。这与then回调的时间相同

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

实例 比如,在输出的第一行900的末尾,是什么信号使执行返回到af1

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

1 af1中的then回调已完成执行,返回一个值undefined,因为它没有返回,这表示WAIT正在等待的承诺值。当当前代码仍在运行直到调用堆栈为空时,这将挂起进行异步处理

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

由于1是微任务队列中的第一个,这是在900已输出且没有更多同步代码执行调用堆栈为空后发生的情况:


JavaScript引擎读取微任务队列,并使用微任务处理第一次等待:函数状态被恢复,包括其循环的状态,循环继续。这意味着promise构造函数回调是同步执行的,在输出的第二行中生成第一个值。。。等等。

让我困惑的是“等待”。具体来说,它如何知道何时恢复执行?@ChongLipPhang,当等待执行的承诺解决或拒绝时。我已经添加了一段关于这一点的内容。让我更清楚一些。比如,在输出的第一行900的末尾,是什么信号让执行返回到af1?我添加了一段关于这一点的内容。顺序是在微任务队列中维护的,而不是堆栈,它是FIFO,作为任务的一部分使用。异步与多线程或并行无关。它总是一个线程,所有同步代码块都以独占方式执行,直到它们完成为止。