ホームページ ウェブフロントエンド jsチュートリアル Node.js_node.js のタイマーについての簡単な説明

Node.js_node.js のタイマーについての簡単な説明

May 16, 2016 pm 03:54 PM
node.js タイマー

Node.js でのタイマーの実装

前のブログ投稿で述べたように、Node のタイマーは新しいスレッドを開いて実装されるのではなく、イベント ループに直接実装されます。以下では、いくつかの JavaScript タイマーの例と Node 関連のソース コードを使用して、タイマー関数が Node でどのように実装されるかを分析します。

JavaScriptのタイマー機能の特徴

Node であってもブラウザであっても、setTimeout と setInterval という 2 つのタイマー関数があり、その動作特性は基本的に同じであるため、以下では分析の例として Node のみを使用します。

JavaScript のタイマーは、コンピューターの基本的なスケジュールされた割り込みと変わらないことがわかっています。割り込みが到着すると、現在実行中のコードが中断され、スケジュールされた割り込み処理関数に転送されます。 JavaScript タイマーが期限切れになると、現在の実行スレッドに実行中のコードがない場合、対応するコールバック関数が実行されます。現在実行中のコードがある場合、JavaScript エンジンはコールバックを実行するために現在のコードを中断しません。 start 新しいスレッドはコールバックを実行しますが、現在のコードが実行された後に処理されます。

console.time('A')
setTimeout(function () {
  console.timeEnd('A');
}, 100);
var i = 0;
for (; i < 100000; i++) { }
ログイン後にコピー

上記のコードを実行すると、最終的な出力時間が約 100ms ではなく、数秒であることがわかります。これは、スケジュールされたコールバック関数が実際にはループが完了する前に実行されず、ループの終わりまで延期されることを示しています。実際、JavaScript コードの実行中はすべてのイベントを処理することはできず、現在のコードが完了するまで新しいイベントを処理する必要があります。これが、時間のかかる JavaScript コードをブラウザで実行するとブラウザが応答しなくなる理由です。この状況に対処するには、Yielding Processes テクニックを使用して、時間のかかるコードを小さなチャンク (チャンク) に分割し、各チャンクが処理された後に setTimeout を 1 回実行し、短期間の経過後に次のチャンクを処理することに同意します。この期間中、アイドル時間中、ブラウザ/ノードはキューに入れられたイベントを処理できます。

補足情報

高度なタイマーと生成プロセスについては、第 22 章「JavaScript 高度なプログラミングの高度なテクニック」第 3 版で詳しく説明されています。

ノードでのタイマー実装

libuv による uv_loop_t 型の初期化

前のブログ投稿では、Node が libuv の uv_run 関数を呼び出して、イベント スケジューリングのためにdefault_loop_ptr を開始すると述べました。default_loop_ptr は、uv_loop_t 型の変数default_loop_struct を指します。ノードが起動すると、uv_loop_init(&default_loop_struct) を呼び出して初期化します。 uv_loop_init 関数の抜粋は次のとおりです。

int uv_loop_init(uv_loop_t* loop) {
 ...
 loop->time = 0;
 uv_update_time(loop);
 ...
}
ログイン後にコピー

最初にループの time フィールドに値 0 が割り当てられ、次に uv_update_time 関数が呼び出され、最新のカウント時間がloop.time に割り当てられることがわかります。

初期化が完了すると、default_loop_struct.time に初期値が設定され、時間関連の操作がこの値と比較され、対応するコールバック関数を呼び出すかどうかが決定されます。

libuv のイベント スケジューリング コア

前述したように、uv_run 関数はイベント ループを実装する libuv ライブラリの中核部分です。以下はそのフローチャートです。

タイマーに関連する上記のロジックを簡単に説明します。

現在のループの概念に基づいて「現在」をマークする現在のループの時間フィールドを更新します。

ループが生きているかどうかを確認します。つまり、ループ内に処理する必要のあるタスク (ハンドラー/リクエスト) があるかどうかを確認します。そうでない場合は、ループする必要はありません。 登録されたタイマーを確認します。タイマーに指定された時間が現在よりも遅れている場合は、タイマーが期限切れになったことを意味し、対応するコールバック関数が実行されます。 I/O ポーリングを実行します (つまり、スレッドをブロックし、I/O イベントが発生するのを待ちます)。次のタイマーが期限切れになったときに I/O が完了していない場合は、待機を停止し、次のタイマーのコールバックを実行します。


I/O イベントが発生すると、対応するコールバックが実行されます。コールバックの実行中に別のタイマーが期限切れになる可能性があるため、タイマーを再度チェックしてコールバックを実行する必要があります。

(実際には、ここでの (4.) は、単なるワンステップ操作ではなく、より複雑です。この説明は、他の詳細を含まず、タイマーの実装に焦点を当てるだけです。)

ノードはループが存在しなくなるまで uv_run を呼び出し続けます。

ノード内の timer_wrap とタイマー

Node には TimerWrap クラスがあり、Node 内で timer_wrap モジュールとして登録されています。

NODE_MODULE_CONTEXT_AWARE_BUILTIN(timer_wrap、node::TimerWrap::Initialize)

TimerWrap クラスは基本的に uv_timer_t を直接カプセル化したもので、NODE_MODULE_CONTEXT_AWARE_BUILTIN は組み込みモジュールを登録するために Node によって使用されるマクロです。


このステップの後、JavaScript はこのモジュールを取得して操作できるようになります。 src/lib/timers.js ファイルは、JavaScript を使用して timer_wrap 関数をカプセル化し、exports.setTimeout、exports.setInterval、exports.setImmediate およびその他の関数をエクスポートします。

ノードの起動とグローバル初期化

前の記事では、Node が開始時に実行環境 LoadEnvironment(env) をロードすると述べました。この関数の非常に重要なステップは、src/node.js をロードし、それを実行することです。src/node.js は指定されたものをロードします。モジュールとグローバルとプロセスを初期化します。もちろん、setTimeout などの関数も src/node.js によってグローバル オブジェクトにバインドされます。

以上がこの記事の全内容です。皆さんに気に入っていただければ幸いです。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、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.js Docker イメージを選択する方法について話しましょう。 最適な Node.js Docker イメージを選択する方法について話しましょう。 Dec 13, 2022 pm 08:00 PM

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

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

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

iPhoneのカメラにタイマーを設定する方法 iPhoneのカメラにタイマーを設定する方法 Apr 14, 2023 am 10:43 AM

iPhone のカメラではどれくらいの時間タイマーを設定できますか? iPhone のカメラ アプリのタイマー オプションにアクセスすると、3 秒 (3s) と 10 秒 (10s) の 2 つのモードから選択するオプションが表示されます。最初のオプションでは、iPhone を持ったまま、前面カメラまたは背面カメラから簡単に自撮り写真を撮ることができます。 2 番目のオプションは、遠くから iPhone を三脚に取り付けて集合写真や自撮り写真をクリックするシーンで便利です。 iPhone のカメラにタイマーを設定する方法 iPhone のカメラにタイマーを設定するのは非常に簡単なプロセスですが、正確な方法は使用している iPhone のモデルによって異なります。

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」をクリックします。

ノードのバッファーについて詳しく見る ノードのバッファーについて詳しく見る Apr 25, 2023 pm 07:49 PM

当初、JS はブラウザ側でのみ動作していたため、Unicode でエンコードされた文字列の処理は簡単でしたが、バイナリ文字列や非 Unicode エンコード文字列の処理は困難でした。バイナリは、コンピュータのビデオ/オーディオ/プログラム/ネットワーク パッケージの最低レベルのデータ形式です。

See all articles