setTimeout に遭遇し、それを次のラウンドのマクロ タスク キューに投入します。Eventloop の現在のラウンドが終了するのを待ってから、2 ラウンド目の実行に進みます。
新しいPromiseに出会うと、中の非同期操作は即座に実行されますが、thenの中のコールバック関数はマイクロタスクキューに投げ込まれます。thenの中のコールバックがその時点でマイクロタスクキューに投入される前に、then以前のPromiseインスタンス内のすべての非同期操作が完了していなければならないことに注意してください。つまり、promiseインスタンスにおいて、resolve()を実行する場合、thenの最初の関数を実行することを意味するだけで、thenのコールバックをキューに入れることはありません。promiseインスタンスがすべての関数を実行し終わるまで、thenのコールバックをマイクロタスクキューに入れず、thenを実行したときにthenのコールバックをマイクロタスクキューに入れます。
async関数では、awaitに遭遇すると、まずawaitに続く関数を実行しに行き、実行が終わるとawaitはスレッドを手放し、awaitに続くステートメント、またはasyncの内部ステートメントをマイクロタスクキューに入れます。
このラウンドの同期コードをすべて実行させると、マイクロタスク・キューに移動し、順番に取り出して実行します。マイクロタスク・キューにあるものがすべて実行されたら、そのラウンドは完了です。
次に、マクロタスクキューの次のラウンドを探し、順番に実行します。
例 1:
async function async1() {
console.log("async1 start");
await async2();
console.log("async1 end");
return 'async return';
}
async function async2() {
console.log("async2");
}
console.log("script start");
setTimeout(function() {
console.log("setTimeout");
}, 0);
async1().then(function (message) { console.log(message) });
new Promise(function(resolve) {
console.log("promise1");
resolve();
}).then(function() {
console.log("promise2");
});
console.log("script end");
たとえば、async1().then は、async1 関数を実行しようとして、内部で await に遭遇し、次の 2 行のコードがマイクロタスクキューに入れられるので、async1 関数の実行はまだ終わっていません。そのため、コールバックはマイクロタスクキューに入れられません。代わりに、async1 のすべてのコードが実行されるまで待ってからマイクロタスクキューに入れられます。
分析プロセス。
"script start"
console.log("setTimeout");-次のマクロタスク
"async1 start"
"async2"
console.log("async1 end"); -マイクロタスク1
return 'async return'; -マイクロタスク2
"promise1"
console.log("promise2"); -マイクロタスク3
"script end"
"async1 end" 1
function (message) { console.log(message) } -マイクロタスク4
"promise2" 3
'async return' 4
"setTimeout"
では、最後の注文です:
"script start"
"async1 start"
"async2"
"promise1"
"script end"
"async1 end"
"promise2"
"async return"
"setTimeout"
例 2:
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout1');
}, 200);
setTimeout(function() {
console.log('setTimeout2');
new Promise(function(resolve) {
resolve();
}).then(function() {
console.log('then1')
})
new Promise(function(resolve) {
console.log('Promise1');
resolve();
}).then(function() {
console.log('then2')
})
},0)
async1();
new Promise(function(resolve) {
console.log('promise2');
resolve();
}).then(function() {
console.log('then3');
});
console.log('script end');
分析
'script start'
200 setTimeout-マクロタスクキュー
0 setTimeout-
'async1 start'
'async2'
await糸を出す,console.log('async1 end'); -マイクロタスクキュー
'promise2'
function() {
console.log('then3');
} -マイクロタスクキュー
'script end'
マイクロタスクを取り出す:
'async1 end'
'then3'
次のラウンドのマクロタスク:0msが最初に実行される
'setTimeout2'
console.log('then1') -マイクロタスクキュー
'Promise1'
console.log('then2') -マイクロタスクキュー
'then1'
'then2'
200ms
'setTimeout1'
最終命令:
"script start"
"async1 start"
"async2"
"promise2"
"script end"
"async1 end"
"then3"
"setTimeout2"
"Promise1"
"then1"
"then2"
"setTimeout1"