目次
libuv
質問
まず、画像を見てみましょう:
まずタイマーの段階について話しましょう。
ポーリング フェーズでは主に 2 つのことを実行します:
チェックフェーズでは主に setImmediate コールバック関数が実行されます。
小总结
案例
了解下浏览器和node的event-loop差异在什么地方
关于 process.nextTick()和setImmediate
process.nextTick()
event-loop核心思维导图
结束语
ホームページ ウェブフロントエンド jsチュートリアル Node.js のイベントループ機構について説明する記事

Node.js のイベントループ機構について説明する記事

Nov 05, 2021 am 09:48 AM
node.js

この記事は、Node.js のイベント ループ (タイム ループ) メカニズムを理解するのに役立ちます。

Node.js のイベントループ機構について説明する記事

今日は、nodeJ のイベント ループについて学びます。イベントループを理解するのは私にとって常に大きな困難でしたが、今回の学習を通じてその困難を突破したいと思いますし、このブログを通してイベントループについての理解と感想を深めていきたいと思っています。

libuv

イベントループを学ぶ前に、まずノードの libuv について理解してください。 libuv は、さまざまなオペレーティング システムでのさまざまな I/O モデルの実装を担当し、さまざまな実装をサードパーティ アプリケーションで使用できる API に抽象化します。

Node.js のイベントループ機構について説明する記事

質問

イベント ループを正式に学習する前に、質問について考えてみましょう

    setTimeout(() => {
      console.log("timer1");
      Promise.resolve().then(() => {
        console.log("promise1");
      });
    }, 0);

    setTimeout(() => {
      console.log("timer2");
      Promise.resolve().then(() => {
        console.log("promise2");
      });
    }, 0);
ログイン後にコピー

このコードは何ですかブラウザで実行した結果でしょうか?

Node.js のイベントループ機構について説明する記事

ノードで実行した結果はどうなりますか?

#ノード 8.6 前:

Node.js のイベントループ機構について説明する記事

##ノード 8.6 後:


Node.js のイベントループ機構について説明する記事なぜこのような結果になるのか、後で分析します!

nodeJs のイベントループ

まず、画像を見てみましょう:

Node.js のイベントループ機構について説明する記事#画像には 6 つのステージ、つまりタイマー、保留中のコールバック、アイドル/準備、ポーリング、チェック、クローズ コールバックが表示されます。

    タイマー フェーズ: 主に setTimeOut、setInterval コールバックを実行します。
  • 保留中のコールバック フェーズ: ネットワーク通信エラー コールバックなどの一部のシステム コール エラーを実行します
  • アイドル/準備フェーズ: システム内でのみ使用されます (このフェーズを制御したり干渉したりすることはできません)
  • ポーリング フェーズ: 新しい I/ を取得します。ファイルを読み取るための I/O コールバックの取得などの O イベント。
  • 適切な状況下では、nodejs はこのフェーズでブロックします

  • チェックフェーズ: setImmediate コールバックを実行します
  • たとえば、sokect を実行します。イベント コールバックの破棄とクローズ
  • 各ステージは、
FIFO

(先入れ先出し) ルールに従って、内部のタスク キュー タスクを実行します。 これら 6 つのステージのうち、タイマー、ポーリング、チェック ステージに焦点を当てます。私たちの日常の開発における非同期タスクのほとんどは、これら 3 つの段階で処理されます。

タイマー

まずタイマーの段階について話しましょう。

タイマーはイベント ループの最初のステージです。Nodejs は期限切れのタイマーがあるかどうかを確認し、期限切れになっている場合はコールバックをキューに入れます。ただし、nodejs は、事前に設定されたイベントが到着したときにすぐにタイマーがコールバックを実行することを保証できません。これは、nodejs によるタイマーの有効期限チェックが必ずしも信頼できるわけではないためです。マシン上で実行されている他のプログラムの影響を受けるか、現在のメインスレッドが発生しました。アイドル状態ではありません。
ここでの不確実性については、公式サイトに例が示されています: まずsetTimeOutを宣言してから、外部からファイルを読み込む このように、ファイルの読み込み操作がタイマー時間を超えた場合、読み込んだファイルは操作によりタイマーのコールバックが遅延します。これは、前述したようにメインスレッドがアイドル状態ではない状況です。

poll

ポーリング フェーズでは主に 2 つのことを実行します:

1. ポーリング フェーズのタスク キューの処理

2タイムアウトになったタイマーがある場合、そのコールバック関数が実行されます

Node.js のイベントループ機構について説明する記事上の図では、次のことも確認できます。

ポーリング タスク キューの実行後ポーリングフェーズ タスク終了後、プリセットsetImmediateが存在するかどうかを確認し、存在する場合はチェックフェーズに入り、存在しない場合はここでnodejsがブロックします。

ここで質問なのですが、投票段階でブロックされてしまうと、設定したタイマーは実行できなくなるのではないでしょうか?

実際には

イベント ループがポーリング フェーズでブロックされている場合、nodejs にはチェック メカニズムがあり、タイマー キューが空かどうかをチェックします。空でない場合は、タイマーに再入力されます。段階。

check

チェックフェーズでは主に setImmediate コールバック関数が実行されます。

小总结

event-loop的每个阶段都有一个队列,当event-loop达到某个阶段之后,将执行这个阶段的任务队列,直到队列清空或者达到系统规定的最大回调限制之后,才会进入下一个阶段。当所有阶段都执行完成一次之后,称event-loop完成一个tick。

案例

上面我们说完了event-loop的理论部分,但是光有理论我们也还是不能很清晰的理解event-loop。下面我们就根据几个demo来更加深入的理解下event-loop!

demo1

    const fs=require('fs')
    fs.readFile('test.txt',()=>{
            console.log('readFile')
            setTimeout(()=>{
                    console.log('settimeout');
            },0)
            setImmediate(()=>{
                    console.log('setImmediate')
            })
    })
ログイン後にコピー

执行结果:

Node.js のイベントループ機構について説明する記事

可见执行结果跟我们前面的分析时一致的!

demo2

    const fs = require("fs");
    const EventEmitter = require("events").EventEmitter;
    let pos = 0;
    const messenger = new EventEmitter();

    messenger.on("message", function (msg) {
      console.log(++pos + " message:" + msg); //
    });

    console.log(++pos + " first"); //

    process.nextTick(function () {
      console.log(++pos + " nextTick"); //
    });

    messenger.emit("message", "hello!");
    fs.stat(__filename, function () {
      console.log(++pos + " stat"); //
    });

    setTimeout(function () {
      console.log(++pos + " quick timer"); //
    }, 0);
    setTimeout(function () {
      console.log(++pos + " long timer"); //
    }, 30);
    setImmediate(function () {
      console.log(++pos + " immediate"); //
    });

    console.log(++pos + " last"); //
ログイン後にコピー

结果:

Node.js のイベントループ機構について説明する記事

了解下浏览器和node的event-loop差异在什么地方

在node 8.6 之前:

浏览器中的微任务队列会在每个宏任务执行完成之后执行,而node中的微任务会在事件循环的各个阶段之间执行,即每个阶段执行完成之后会去执行微任务队列。

在8.6之后:

浏览器和node中微任务的执行是一致的!

所以,在文章开头,我们提出的思考的问题就有了结果。

关于 process.nextTick()和setImmediate

process.nextTick()

语法:process.nextTick(callback,agrs)

执行时机:

这个函数其实是独立于 Event Loop 之外的,它有一个自己的队列,当每个阶段完成后,如果存在 nextTick 队列,就会清空队列中的所有回调函数,并且优先于其他 microtask 执行。递归的调用process.nextTick()会导致I/O starving,官方推荐使用setImmediate()

关于starving现象的说明:

    const fs = require("fs");
    fs.readFile("test.txt", (err, msg) => {
      console.log("readFile");
    });

    let index = 0;

    function handler() {
      if (index >= 30) return;
      index++;
      console.log("nextTick" + index);
      process.nextTick(handler);
    }

    handler();
ログイン後にコピー

运行结果:

Node.js のイベントループ機構について説明する記事

可以看到,等到nextTick函数呗执行30次之后,读取文件的回调才被执行!这样的现象被称为 I/O 饥饿

当我们把 process.nextTick 换为 setImmediate

    const fs = require("fs");
    fs.readFile("test.txt", (err, msg) => {
      console.log("readFile");
    });

    let index = 0;

    function handler() {
      if (index >= 30) return;
      index++;
      console.log("nextTick" + index);
      setImmediate(handler);
    }

    handler();
ログイン後にコピー

结果:

Node.js のイベントループ機構について説明する記事

造成这两种差异的原因是,嵌套调用的setImmediate的回调被排到了下一次event-loop中去!

event-loop核心思维导图

1Node.js のイベントループ機構について説明する記事

结束语

通过今天的学习,让我对event-loop的理解更深刻了。那么,下次见。好好学习,天天向上!

1Node.js のイベントループ機構について説明する記事

更多编程相关知识,请访问:编程视频!!

以上がNode.js のイベントループ機構について説明する記事の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Nodeのメモリ制御に関する記事 Nodeのメモリ制御に関する記事 Apr 26, 2023 pm 05:37 PM

ノンブロッキングおよびイベント駆動に基づいて構築されたノード サービスには、メモリ消費量が少ないという利点があり、大量のネットワーク リクエストの処理に非常に適しています。大量のリクエストを前提として、「メモリ制御」に関する問題を考慮する必要があります。 1. V8 のガベージ コレクション メカニズムとメモリ制限 Js はガベージ コレクション マシンによって制御されます

Node V8 エンジンのメモリと GC の詳細な図による説明 Node V8 エンジンのメモリと GC の詳細な図による説明 Mar 29, 2023 pm 06:02 PM

この記事では、NodeJS V8 エンジンのメモリとガベージ コレクター (GC) について詳しく説明します。

Node の File モジュールについて詳しく説明しましょう Node の File モジュールについて詳しく説明しましょう Apr 24, 2023 pm 05:49 PM

ファイル モジュールは、ファイルの読み取り/書き込み/開く/閉じる/削除の追加など、基礎となるファイル操作をカプセル化したものです。ファイル モジュールの最大の特徴は、すべてのメソッドが **同期** と ** の 2 つのバージョンを提供することです。 asynchronous**、sync サフィックスが付いているメソッドはすべて同期メソッドであり、持たないメソッドはすべて異種メソッドです。

最適な Node.js Docker イメージを選択する方法について話しましょう。 最適な Node.js Docker イメージを選択する方法について話しましょう。 Dec 13, 2022 pm 08:00 PM

ノード用の Docker イメージの選択は些細なことのように思えるかもしれませんが、イメージのサイズと潜在的な脆弱性は、CI/CD プロセスとセキュリティに大きな影響を与える可能性があります。では、最適な Node.js Docker イメージを選択するにはどうすればよいでしょうか?

Node.js 19 が正式リリースされました。その 6 つの主要な機能についてお話しましょう。 Node.js 19 が正式リリースされました。その 6 つの主要な機能についてお話しましょう。 Nov 16, 2022 pm 08:34 PM

Node 19 が正式リリースされましたので、この記事では Node.js 19 の 6 つの主要な機能について詳しく説明します。

Node.js の GC (ガベージ コレクション) メカニズムについて話しましょう Node.js の GC (ガベージ コレクション) メカニズムについて話しましょう Nov 29, 2022 pm 08:44 PM

Node.js はどのように GC (ガベージ コレクション) を行うのでしょうか?次の記事で詳しく説明します。

Nodeのイベントループについて話しましょう Nodeのイベントループについて話しましょう Apr 11, 2023 pm 07:08 PM

イベント ループは Node.js の基本的な部分であり、メイン スレッドがブロックされていないことを確認することで非同期プログラミングが可能になります。イベント ループを理解することは、効率的なアプリケーションを構築するために重要です。次の記事では、Node のイベント ループについて詳しく説明します。お役に立てれば幸いです。

ノードがnpmコマンドを使用できない場合はどうすればよいですか? ノードがnpmコマンドを使用できない場合はどうすればよいですか? Feb 08, 2023 am 10:09 AM

ノードが npm コマンドを使用できない理由は、環境変数が正しく設定されていないためです。解決策は次のとおりです: 1. 「システムのプロパティ」を開きます; 2. 「環境変数」->「システム変数」を見つけて、環境を編集します。変数; 3.nodejs フォルダーの場所を見つけます; 4.「OK」をクリックします。

See all articles