次のコードの実行方法を理解できません。 「1」が「b」の後にあるのに「h」が「3」の後にあるのはなぜですか?順序は次のとおりです:a、b、1、2、h、3?一部の記事では、「イベントループキュー」と「ジョブキュー」の違いが次の出力につながると述べています。しかし、どうやって?私は ECMAScript 2015-8.4ジョブとジョブキュー の仕様を読み、Promise'jobがどのように機能するかを知りたいと思っていますが、混乱します。誰かが私を助けてくれますか?ありがとうございました!
var promise = new Promise(function(resolve, reject) {resolve(1)});
promise.then(function(resolve) {console.log(1)});
console.log('a');
promise.then(function(resolve) {console.log(2);});
setTimeout(function() {console.log('h')}, 0);
promise.then(function(resolve) {console.log(3)});
console.log('b');
// a
// b
// 1
// 2
// 3
// h
私はPromiseが非同期であることを知っていますが、setTimeout(..)非同期操作のコールバックは常にPromiseの非同期操作の後で行われます。どうして?
なぜ「1」が「b」の後ろにあるのですか?
Promise仕様では、JSの現在のスレッドが完了するまで実行された後、すべてのpromise .then()
ハンドラーが非同期で呼び出されます。したがって、現在のJSの一部として同期的に実行されるa
とb
は、.then()
ハンドラーの前に実行されるため、1
は常にa
とb
の後にあります。
いくつかの興味深い読み物:T 質問、マイクロタスク、キュー、およびスケジュール および JavaScriptのpromiseでの実行順序は何ですか および JavaScriptフレームワークの記述-実行タイミング、それ以降setTimeout 。
このスレッドには、いくつかの良いアドバイスがあります: 約束は、nextTick
とsetImmediate
の間で少しずつ変わります :
非連鎖イベントの正確な実行順序に依存することはお勧めしません。実行順序を制御したい場合—後で実行するコールバックが前に実行するコールバックに依存するようにコールバックを再配置するか、キューを実装します(内部で同じことを行います) )。
言い換えると、非同期イベントの特定のタイミングに依存している場合は、実際にコードでそれらを連鎖させて、実装での不特定のスケジューリングに依存するのではなく、コードを介して順番に実行する必要があります。
これはJSを初めて使う人にとってはわかりやすいものです。
これは@getifyの本からコピーして貼り付けたものです
メタファーを使用するには:イベントループキューは遊園地の乗り物に似ています。乗り物が終わったら、もう一度乗るために列の後ろに移動する必要があります。しかし、ジョブキューはライドを終えるようなものですが、その後、列に並んで正しい状態に戻ります。
イベントループキュー-promise以外のすべての非同期コールバック、h
ジョブキュー-promiseに関連するすべての非同期コールバック用。 1、2、3
同期-a、b