クライアント側のJavaScriptプログラミングに精通している場合は、SettimeOutおよびSetInterval関数を使用している可能性があります。たとえば、次のコードは、1秒後にWebページにロードされたら、ページのドキュメントの後に「Hello There」が追加されます。
コードコピーは次のとおりです。
VAR ONESECOND = 1000 * 1; // 1秒= 1000 x 1 ms
setimeout(function(){
document.write( '<p>こんにちは。</p>');
}、oneecond);
SetIntervalにより、指定された時間間隔で関数の繰り返し実行が可能になります。次のコードがWebページに挿入された場合、次の文「Hello There」が毎秒ページドキュメントに追加されます。
コードコピーは次のとおりです。
VAR ONESECOND = 1000 * 1; // 1秒= 1000 x 1 ms
setInterval(function(){
document.write( '<p>こんにちは。</p>');
}、oneecond);
Webは長い間、単純な静的ページではなく、アプリケーションを構築するためのプラットフォームになっているため、この種の同様の需要がますます出現しています。これらのタスク計画関数は、開発者がフォームの定期的な検証を実装したり、リモートデータの同期を遅らせたり、応答を遅らせるUIインタラクションを実装するのに役立ちます。また、ノードはこれらの方法を完全に実装します。サーバー側では、それらを使用して、キャッシュの有効期限、接続プールのクリーニング、セッションの有効期限、ポーリングなど、多くのタスクの実行を繰り返しまたは遅らせることができます。
Settimeout Delay関数を使用して実行します
SettimeOutは、次のような将来の特定の時間に一度指定された関数を実行する実行計画を作成できます。
コードコピーは次のとおりです。
var timeout_ms = 2000; // 2秒
var timeout = setimeout(function(){
console.log( "タイムアウト!");
}、timeout_ms);
クライアントJavaScriptと同様に、SettimeOutは2つのパラメーターを受け入れます。最初のパラメーターは、遅延が必要な関数であり、2番目のパラメーターは遅延時間(ミリ秒単位)です。
Settimeoutは、内部オブジェクトであるタイムアウトハンドルを返します。パラメーターとして使用して、ClearTimeoutを呼び出してタイマーをキャンセルできます。それを除いて、このハンドルには効果がありません。
ClearTimeoutを使用して、実行計画をキャンセルします
タイムアウトハンドルが取得されたら、ClearTimeoutを使用して、次のような機能実行計画をキャンセルできます。
コードコピーは次のとおりです。
var timeouttime = 1000; // 1秒
var timeout = setimeout(function(){
console.log( "タイムアウト!");
}、timeouttime);
ClearTimeout(Timeout);
この例では、タイマーがトリガーされることはなく、「タイムアウト!」という単語を出力しません。次の例のように、将来いつでも実行計画をキャンセルすることもできます。
コードコピーは次のとおりです。
var timeout = setimeout(function a(){
console.log( "タイムアウト!");
}、2000);
setimeout(function b(){
ClearTimeout(Timeout);
}、1000);
コードは、実行された2つの関数AとBを指定します。関数Aは2秒後に実行される予定であり、関数Bが最初に実行され、Aの実行計画をキャンセルするため、Bは1秒後に実行される予定であるため、Aは実行されません。
関数の反復実行計画を開発してキャンセルする
SetIntervalはSettimeoutに似ていますが、指定された時間間隔で関数を繰り返し実行します。それを使用して、クリーニング、収集、ロギング、データの取得、ポーリングなど、繰り返し必要な他のタスクを完了するためにプログラムを定期的にトリガーすることができます。
次のコードは、毎秒コンソールに「ティック」を出力します。
コードコピーは次のとおりです。
var期間= 1000; // 1秒
setInterval(function(){
console.log( "tick");
}、 期間);
永久に実行したくない場合は、ClearInterval()を使用してタイマーをキャンセルできます。
setIntervalは、実行計画をキャンセルするためにclearintervalのパラメーターとして使用できます。
コードコピーは次のとおりです。
var interval = setInterval(function(){
console.log( "tick");
}、1000);
//…
ClearInterval(間隔);
プロセスを使用して、イベントループの次のラウンドに関数実行を遅らせる
クライアントJavaScriptプログラマがSettimeout(Callback、0)を使用して、タスクを短時間遅らせることがあります。 2番目のパラメーターは0ミリ秒です。 JavaScriptに、すべての保留中のイベントが処理された直後にこのコールバック関数を実行するように指示します。この手法は、すぐに実行する必要のない操作の実行を遅らせるために使用される場合があります。たとえば、ユーザーイベントが処理された後、アニメーションの再生を開始したり、他の計算を行う必要がある場合があります。
ノードでは、「イベントループ」の文字通りの意味と同様に、イベントループはイベントキューを処理するループで実行され、イベントループ作業の各ラウンドはティックと呼ばれます。
イベントループが次のラウンド(次のティック)実行を開始するたびにコールバック関数を1回呼び出すことができます。これはまさにProcess.nextTickの原則であり、SetimeoutであるSetimeoutは、イベントループを使用する代わりにJavaScriptランタイム内の実行キューを使用します。
settimeout(callback、0)の代わりにprocess.nexttick(callback)を使用することにより、キューでのイベントが処理された直後にコールバック関数が実行されます。 JavaScriptタイムアウトキュー(CPU時間で測定)よりもはるかに高速です。
次のイベントループまで機能を遅らせて、次のように実行できます。
コードコピーは次のとおりです。
process.nexttick(function(){
my_expiense_computation_function();
});
注:プロセスオブジェクトは、ノード内の数少ないグローバルオブジェクトの1つです。
ブロックイベントループ
ノードとJavaScriptのランタイムは、シングルスレッドイベントループを使用します。各ループ、ランタイムはコールバック関数を使用して、キューの次のイベントを処理します。イベントが実行されると、イベントループは実行結果を取得し、次のイベントを処理し、イベントキューが空になるまでこれを繰り返します。コールバックの1つが実行に時間がかかる場合、イベントループはその間に他の保留中のイベントを処理できず、アプリケーションやサービスを非常に遅くすることができます。
イベントを処理する場合、メモリに敏感またはプロセッサに敏感な関数が使用される場合、イベントループが遅くなり、多数のイベントが蓄積されます。これは時間内に処理できません。
イベントループのブロックの次の例を参照してください。
コードコピーは次のとおりです。
process.nexttick(function nexttick1(){
var a = 0;
while(true){
a ++;
}
});
process.nexttick(function nexttick2(){
console.log( "次のティック");
});
setimeout(function timeout(){
console.log( "Timeout");
}、1000);
この例では、次のTick2とタイムアウト関数は、どれだけ長く待っても実行する機会がありません。イベントループは次のティック関数の無限ループによってブロックされ、タイムアウト関数が1秒後に実行されても実行されない場合でも実行されません。
SettimeOutを使用すると、コールバック機能が実行計画キューに追加され、この場合はキューに追加されません。これは極端な例ですが、プロセッサに敏感なタスクを実行すると、イベントループをブロックまたは遅くすることができることがわかります。
イベントループを終了します
プロセスを使用して、実行前に非クリティカルなタスクをイベントループ(ティック)の次のラウンドに延期できます。これにより、イベントループを解放して、他の保留中のイベントを実行し続けることができます。
次の例を参照してください。一時ファイルを削除する予定であるが、データイベントのコールバック関数がこのIO操作を待つ必要がない場合は、次のように遅らせることができます。
コードコピーは次のとおりです。
stream.on( "data"、function(data){
Stream.End( "My Response");
process.nexttick(function(){
fs.unlink( "/path/to/file");
});
});
setimeoutの代わりにsettimeoutを使用して、機能実行のシラリティを確保する
My_async_functionという関数を設計する予定であるとします。これにより、一部のI/O操作(ログファイルの解析など)を実行し、定期的に実行することを意図しています。このようなsetintervalで実装できます。
コードコピーは次のとおりです。
var interval = 1000;
setInterval(function(){
my_async_function(function(){
console.log( 'my_async_function finent!');
});
}、interval); //翻訳者のメモ:前の「インターバル」を追加しました、そして、著者はタイプミスのためにそれを見逃したはずです
これらの関数が同時に実行されないことを確認できる必要がありますが、SetIntervalを使用する場合、これを保証することはできません。 my_async_function関数が間隔変数よりも1ミリ秒長く実行される場合、それらは順番に連続的にではなく、同時に実行されます。
翻訳者のメモ:(以下の大胆な部分は、元の本の内容ではなく、翻訳者によって追加されます)
コンテンツのこの部分の理解を促進するために、著者のコードを実際に実行できるように変更できます。
コードコピーは次のとおりです。
var interval = 1000;
setInterval(function(){
(機能my_async_function(){
setimeout(function(){
console.log( "1");
}、5000);
})();
}、間隔);
このコードを実行すると、5秒間待った後、「Hello」が1秒ごとに出力されることがわかります。現在のmy_async_functionが実行された後(5秒かかった)、次のmy_async_functionを実行する前に1秒待って、各出力間の間隔は6秒であると予想されます。この結果は、my_async_functionが連続的に実行されるのではなく、同時に実行されるためです。
したがって、my_async_functionの実行の終了と次のmy_async_functionの実行の開始との間隔を強制する方法が必要です。間隔変数で指定された時間です。あなたはこれを行うことができます:
コードコピーは次のとおりです。
var interval = 1000; // 1秒
(関数スケジュール(){// 3行目
setimeout(function do_it(){
my_async_function(function(){//行5
console.log( 'async is done!');
スケジュール();
});
}、interval);
}()); // 10行目
前のコードでは、スケジュール(3行目)と呼ばれる関数が宣言され、宣言直後(10行目)と呼ばれます。スケジュール関数は、1秒後にDO_IT関数を実行します(間隔で指定)。 1秒後、5行目のmy_async_function関数が呼び出されます。実行されると、独自の匿名コールバック関数(6行目)を呼び出します。この匿名のコールバック関数は、DO_ITの実行計画を再度リセットし、1秒後に再度実行して、コードがシリーナにかつ継続的に実行されるようにします。
まとめ
Settimeout()関数を使用して、関数の実行計画をプリセットし、ClearTimeout()関数でキャンセルできます。 SetInterval()を使用して、特定の関数を定期的に繰り返し実行することもできます。したがって、ClearInterval()を使用して、この繰り返しの実行計画をキャンセルできます。
イベントループがプロセッサに敏感な操作を使用してブロックされている場合、もともと実行されると計画されていた機能が遅れ、実行されることはありません。したがって、イベントループ内でCPUに敏感な操作を使用しないでください。また、process.nexttick()を使用して、イベントループの次のラウンドまで関数の実行を遅らせることができます。
I/OとSetInterval()を一緒に使用する場合、いつでも保留中の通話が1つだけあることを保証することはできませんが、再帰関数とSettimeout()関数を使用して、このトリッキーな問題を回避できます。