ホームページ > 記事 > ウェブフロントエンド > Node.js_node.js でタイマーを使用して関数を定期的に実行する方法の詳細な説明
クライアント側の JavaScript プログラミングに精通している場合は、関数の実行を一定期間遅延できる setTimeout 関数と setInterval 関数を使用したことがあるかもしれません。たとえば、次のコードは Web ページに読み込まれると、1 秒後にページのドキュメントに「Hello there」を追加します。
document.write('
こんにちは。
');}, oneSecond);
document.write('
こんにちは。
');}, oneSecond);
setTimeout 遅延関数を使用して を実行します
setTimeout は、指定された関数を将来 1 回実行するための実行計画を作成できます。次に例を示します。
console.log("タイムアウト!");
}、timeout_ms);
setTimeout は内部オブジェクトであるタイムアウト ハンドルを返します。これをパラメータとして使用して、タイマーをキャンセルすることができます。それ以外の場合、このハンドルは効果がありません。
clearTimeout を使用して実行計画をキャンセルします
タイムアウト ハンドルを取得したら、次のように、clearTimeout を使用して関数の実行計画をキャンセルできます。
console.log("タイムアウト!");
}, timeoutTime);
clearTimeout(タイムアウト);
この例では、タイマーはトリガーされず、「タイムアウト!」という言葉も出力されません。次の例のように、将来いつでも実行計画をキャンセルすることもできます。
関数の繰り返し実行計画の作成とキャンセル
setInterval は setTimeout に似ていますが、指定された間隔で関数を繰り返し実行します。これを使用すると、プログラムを定期的にトリガーして、クリーニング、収集、ロギング、データ取得、ポーリングなど、繰り返し実行する必要があるタスクを完了できます。次のコードは、コンソールに毎秒「ティック」を出力します。
console.log("tick");
}、ピリオド);
setInterval は、実行計画ハンドルを返します。これは、実行計画をキャンセルするための clearInterval のパラメータとして使用できます。
}, 1000);
// …
clearInterval(間隔);
process.nextTick を使用して、イベント ループの次のラウンドまで関数の実行を遅らせます
クライアント側の JavaScript プログラマは、setTimeout(callback,0) を使用してタスクを短期間遅延させることがあります。2 番目のパラメータは 0 ミリ秒で、保留中のイベントがすべて処理された後すぐに待機するように JavaScript ランタイムに指示します。このコールバック関数を実行します。この手法は、すぐに実行する必要のない操作の実行を遅らせるために使用されることがあります。たとえば、ユーザー イベントの処理後に、アニメーションの再生を開始したり、その他の計算を実行したりする必要がある場合があります。
Node では、文字通りの意味の「イベント ループ」と同様に、イベント ループはイベント キューを処理するループ内で実行され、イベント ループの作業プロセスの各ラウンドはティックと呼ばれます。
イベント ループが次の実行ラウンド (次のティック) を開始するたびに、コールバック関数を 1 回呼び出すことができます。これはまさに process.nextTick の原理であり、setTimeout と setTimeout は JavaScript ランタイム内の実行キューを使用します。イベントループを使用しません。
setTimeout(callback, 0) の代わりに process.nextTick(callback) を使用すると、キュー内のイベントが処理された直後にコールバック関数が実行されます。これは、JavaScript のタイムアウト キューよりもはるかに高速です (測定する CPU 時間)。 )。
次のように、イベント ループの次のラウンドまで関数を遅らせることができます:
my_expensive_computation_function();
});
注: プロセス オブジェクトは、Node 内の数少ないグローバル オブジェクトの 1 つです。
イベントループのブロック
Node と JavaScript のランタイムはシングルスレッドのイベント ループを使用し、ループするたびに、関連するコールバック関数を呼び出してキュー内の次のイベントを処理します。イベントが実行されると、イベント ループは実行結果を取得して次のイベントを処理し、イベント キューが空になるまでこれが繰り返されます。いずれかのコールバック関数の実行に時間がかかる場合、その間、イベント ループは他の保留中のイベントを処理できなくなり、アプリケーションまたはサービスが非常に遅くなる可能性があります。
イベントを処理するときに、メモリに依存する関数やプロセッサに依存する関数が使用されると、イベント ループが遅くなり、大量のイベントが蓄積されて時間内に処理できなくなったり、キューがブロックされたりすることがあります。
イベント ループをブロックする次の例を見てください:
var a = 0;
while(true) {
;
}
});process.nextTick(function nextTick2() {
console.log("次のティック");
});
setTimeout(関数タイムアウト() {
console.log("タイムアウト");
}, 1000);
setTimeout を使用すると、コールバック関数が実行計画キューに追加されますが、この例ではキューに追加されません。これは極端な例ですが、プロセッサを大量に使用するタスクを実行すると、イベント ループがブロックされたり、速度が低下したりする可能性があることがわかります。
イベントループを終了します
process.nextTick を使用すると、重要ではないタスクをイベント ループの次のラウンド (ティック) に延期できます。これにより、イベント ループが解放され、他の保留中のイベントの実行を継続できるようになります。次の例を見てください。一時ファイルを削除する予定だが、データ イベントのコールバック関数がこの IO 操作を待機しないようにする場合は、次のように遅延できます。
process.nextTick(function() {
fs.unlink("/path/to/file");
});
特定の I/O 操作 (ログ ファイルの解析など) を実行できる my_async_function という関数を設計し、それを定期的に実行できるようにする予定だとします。次のように setInterval を使用して実装できます。
setInterval(function() {
my_async_function(function() {
console.log('my_async_function が完了しました!');
},interval);//翻訳者注: 前の「,interval」は私が追加したもので、著者がタイプミスのために省略した可能性があります
訳者注: (以下の太字部分は訳者によって追加されたものであり、原書の内容ではありません)
コンテンツのこの部分の理解を容易にするために、作成者のコードを変更して実際に実行できるようにすることができます。
(関数 my_async_function(){
setTimeout(function(){
console.log("1");
},5000);
},間隔);
このコードを実行して見てください。5 秒待つと、1 秒ごとに「hello」が出力されることがわかります。現在の my_async_function が実行された後 (5 秒かかります)、次の my_async_function を実行する前に 1 秒待機することが予想されます。各出力の間には 6 秒の間隔が必要です。この結果は、my_async_function がシリアルに実行されず、複数の関数が同時に実行されていることが原因で発生します。