NodeJSイベントループの順序が間違っています

Ievgeniii

私のエクスプレスコード:

app.use('/test', async (req, res, next) => {
  try {
    setTimeout(() => console.log('setTimeout')); // setTimeout (macrotask)
    User.findOne().then(user => console.log('user')); // promise (microtask)
    console.log('console.log');
  } catch (err) {
    next(err);
  }
});

コンソールの出力順序は次のとおりです。

console.log
setTimeout
user

質問:なぜマイクロタスクはマクロタスクの後に実行されるのですか?

たとえば、ブラウザでは、次のコードが正しい順序で解決されます。

コード:

setTimeout(function timeout() {
  console.log(3);
}, 0);

let p = new Promise(function (resolve, reject) {
  for (let i = 0; i < 1e10; i++) {}
  resolve();
});

p.then(function () {
  console.log(2);
});

console.log(1);

注文:

1
2
3
ニック・パーソンズ

マイクロタスクを最初に実行するには、マクロタスクをマクロタスクキューからデキューする前に、マイクロタスクをキューに入れる必要があります。.findOne()時間がかかるため、マイクロタスクは.findOne()setTimeoutコールバックがマクロタスクキューに追加されてからコールスタックにデキューされて実行された後に発生する、resolvesによって返されるpromiseまでキューに入れられません

.findOne()作成しているPromiseのエグゼキュータ関数が同期的に実行されるため、「動作する」コードはNodeプログラムの状況とは異なります(実際、このコードはNodeでも1、2、3を生成することがわかります) :

setTimeout(function timeout() { // <--- queue `timeout` callback as a macro-task
  console.log(3);
}, 0);

let p = new Promise(function (resolve, reject) { // run this function synchronously
  for (let i = 0; i < 1e10; i++) {} // <--- wait here for the loop to complete
  resolve();
});
// Only reached once the loop above has complete, as thus, your promise has resolved 
p.then(function () { // <--- `p` has resolved, so we queue the function as a micro-task
  console.log(2);
});

console.log(1); // <--- add the function to call stack (first log to execute)

上記では、スクリプトの実行中に、setTimeoutコールバックと.then()コールバックの両方がそれぞれのタスクキューに追加されるため、スクリプトの実行が終了すると、マイクロタスクをデキューしてスタックに配置できます。 、次に、マクロタスクを要求してスタックに配置できます。

あなたのコードは異なります:

/* 
setTimeout gets added to the callstack, that spins off an API which after 0 m/s adds your callback to the macro-task queue
*/
setTimeout(() => console.log('setTimeout')); 

/* 
.findOne() gets added to the call stack, that spins off an API which after N m/s adds the `.then()` callback to the micro-task queue (N > 0)
*/
User.findOne().then(user => console.log('user')); // promise (microtask)

/* 
While the above API is working in the background, our script can continue on...
console.log() gets added to the call stack and "console.log" gets logged
*/
console.log('console.log');

上記のスクリプトが終了すると、timeoutコールバックはマクロタスクキューにあり.then()ますが、クエリはまだバックグラウンドで実行されているため、コールバックはまだマイクロタスクキューにありません。次に、timeoutコールバックはコールスタックにデキューされます。しばらくすると、.then()コールバックがマイクロタスクキューに追加され、コールスタックが空になると実行され、キューからスタックに移動されます。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

FlutterFirebaseデータベースのタイムスタンプの順序が間違っています

分類Dev

luaテーブルのループ順序が間違っています

分類Dev

ソートコマンドの順序が間違っています

分類Dev

tfrecordsからデータをインポートするときに、バッチ処理後にラベルの順序が間違っている

分類Dev

forループが間違った順序で印刷されています

分類Dev

ページのタイトルとコンテンツの順序が間違っている (wordpress/bootstrap/php)

分類Dev

バイナリコードの順序が間違っています-正しくシフトする方法は?

分類Dev

フィールドリストでの並べ替えの順序が間違っています

分類Dev

ListBoxItem DelphiXE5のアイテムの順序が間違っています

分類Dev

ggplotbarplotのy軸の順序が間違っています

分類Dev

グループ内で順序が間違っている行を削除する

分類Dev

CSVからAccessにインポートするときにフィールドの順序が間違っている

分類Dev

form:radiobuttonsのリストの順序が間違っています

分類Dev

PriorityQueue.toString要素の順序が間違っています

分類Dev

Postgresの順序が間違っています

分類Dev

jQuery prepend()とJSONの順序が間違っています

分類Dev

フルカレンダー:イベントの終了時刻が間違っています

分類Dev

動的高さUITableViewCellデータの順序が間違っています

分類Dev

A-透明な画像のフレームカーソルの描画順序が間違っています

分類Dev

ソートされたファイルをMacOS Xで印刷する(順序が間違っている)

分類Dev

CAT5ケーブルの順序が間違っています-それは重要ですか?

分類Dev

GraphQLリゾルバー引数(root、args、context)の順序が間違っています

分類Dev

棒グラフのラベルの順序が間違っている

分類Dev

テンプレートパラメータが間違った順序で配置されています。それが正しいか?

分類Dev

Reactコンポーネントの状態、応答からの配列内のオブジェクトの順序が間違っています

分類Dev

CommonsChunkPluginを使用したWebpackの結果、htmlファイルのバンドル順序が間違っています

分類Dev

dictのpandasデータフレームは文字列インデックスを保持します(順序が間違っています)

分類Dev

Chromeでテキストボックスのクリックイベントとフォーカスイベントの順序が間違っていませんか?

分類Dev

Chromeでテキストボックスのクリックイベントとフォーカスイベントの順序が間違っていませんか?

Related 関連記事

  1. 1

    FlutterFirebaseデータベースのタイムスタンプの順序が間違っています

  2. 2

    luaテーブルのループ順序が間違っています

  3. 3

    ソートコマンドの順序が間違っています

  4. 4

    tfrecordsからデータをインポートするときに、バッチ処理後にラベルの順序が間違っている

  5. 5

    forループが間違った順序で印刷されています

  6. 6

    ページのタイトルとコンテンツの順序が間違っている (wordpress/bootstrap/php)

  7. 7

    バイナリコードの順序が間違っています-正しくシフトする方法は?

  8. 8

    フィールドリストでの並べ替えの順序が間違っています

  9. 9

    ListBoxItem DelphiXE5のアイテムの順序が間違っています

  10. 10

    ggplotbarplotのy軸の順序が間違っています

  11. 11

    グループ内で順序が間違っている行を削除する

  12. 12

    CSVからAccessにインポートするときにフィールドの順序が間違っている

  13. 13

    form:radiobuttonsのリストの順序が間違っています

  14. 14

    PriorityQueue.toString要素の順序が間違っています

  15. 15

    Postgresの順序が間違っています

  16. 16

    jQuery prepend()とJSONの順序が間違っています

  17. 17

    フルカレンダー:イベントの終了時刻が間違っています

  18. 18

    動的高さUITableViewCellデータの順序が間違っています

  19. 19

    A-透明な画像のフレームカーソルの描画順序が間違っています

  20. 20

    ソートされたファイルをMacOS Xで印刷する(順序が間違っている)

  21. 21

    CAT5ケーブルの順序が間違っています-それは重要ですか?

  22. 22

    GraphQLリゾルバー引数(root、args、context)の順序が間違っています

  23. 23

    棒グラフのラベルの順序が間違っている

  24. 24

    テンプレートパラメータが間違った順序で配置されています。それが正しいか?

  25. 25

    Reactコンポーネントの状態、応答からの配列内のオブジェクトの順序が間違っています

  26. 26

    CommonsChunkPluginを使用したWebpackの結果、htmlファイルのバンドル順序が間違っています

  27. 27

    dictのpandasデータフレームは文字列インデックスを保持します(順序が間違っています)

  28. 28

    Chromeでテキストボックスのクリックイベントとフォーカスイベントの順序が間違っていませんか?

  29. 29

    Chromeでテキストボックスのクリックイベントとフォーカスイベントの順序が間違っていませんか?

ホットタグ

アーカイブ