Javascript ECMAScript-2017中“异步函数”的异步程度如何?
大约一个月前刚刚定稿的ECMAScript-2017引入了一项新功能。为了了解它们的“异步”程度,我在Chrome中进行了一项测试: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
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,作为任务的一部分使用。异步与多线程或并行无关。它总是一个线程,所有同步代码块都以独占方式执行,直到它们完成为止。