それが実行されるとキューにあると思いますが、キューでは、Xミリ秒後に正確に呼び出されるという保証はありますか?または、キューの上位にある他の重いタスクはそれを遅らせますか?
それが実行されるとキューにあると思いますが、キューでは、Xミリ秒後に正確に呼び出されるという保証はありますか?または、キューの上位にある他の重いタスクはそれを遅らせますか?
回答:
setTimeoutのセマンティクスは、Webブラウザーとほぼ同じです。タイムアウト引数は、実行前に待機する最小ミリ秒数であり、保証ではありません。さらに、0、非数値、または負の数値を渡すと、最小ミリ秒待機します。ノードではこれは1ミリ秒ですが、ブラウザでは50ミリ秒にもなることがあります。
これは、JavaScriptによるJavaScriptの優先権がないためです。この例を考えてみましょう:
setTimeout(function () {
console.log('boo')
}, 100)
var end = Date.now() + 5000
while (Date.now() < end) ;
console.log('imma let you finish but blocking the event loop is the best bug of all TIME')
ここでの流れは:
そうでない場合は、JavaScriptのビットをもう1つ「中断」させることができます。このようなコードが次のことを推論するのが非常に困難になるのを防ぐために、ミューテックスやセマフォーなどを設定する必要があります。
var a = 100;
setTimeout(function () {
a = 0;
}, 0);
var b = a; // 100 or 0?
NodeのJavaScript実行はシングルスレッド化されているため、他のほとんどの同時方式よりもはるかに簡単に操作できます。もちろん、トレードオフは、プログラムの不適切な動作をする部分がすべてを無限ループでブロックする可能性があることです。
これは、プリエンプションの複雑さよりも戦闘に適した悪魔ですか?場合によります。
console.log
メッセージの+1を受け取ります。
ノンブロッキングの考え方は、ループの反復が速いということです。したがって、ティックごとに繰り返すには、setTimeoutが妥当な精度(おそらく100ミリ秒程度オフ)まで正確になるまでに十分な時間がかかる必要があります。
理論的にはあなたは正しいです。アプリケーションを作成してティックをブロックすると、setTimeoutsが遅延します。それであなたが質問に答えるために、setTimeoutsが時間通りに実行されることを誰が保証できるのでしょうか?ノンブロッキングコードを作成することで、ほぼすべての妥当な精度まで精度を制御できます。
コードの実行(Webワーカーなどを除く)に関してJavaScriptが「シングルスレッド」である限り、それは常に起こります。シングルスレッドの性質は、ほとんどの場合非常に単純化されていますが、成功するためにはノンブロッキングイディオムが必要です。
ブラウザまたはノードでこのコードを試してみてください。正確さが保証されていないことがわかります。逆に、setTimeoutは非常に遅くなります。
var start = Date.now();
// expecting something close to 500
setTimeout(function(){ console.log(Date.now() - start); }, 500);
// fiddle with the number of iterations depending on how quick your machine is
for(var i=0; i<5000000; ++i){}
インタプリタがループを最適化しない限り(これはクロムではありません)、何千もの結果が得られます。ループを外すと、鼻に500と表示されます...
コードが確実に実行される唯一の方法は、setTimeoutロジックを別のプロセスに配置することです。
子プロセスモジュールを使用して、ロジックを実行する新しいnode.jsプログラムを生成し、ある種のストリーム(おそらくtcp)を介してそのプロセスにデータを渡します。
この方法では、メインプロセスで長いブロッキングコードが実行されている場合でも、子プロセスはすでにそれ自体を起動しており、setTimeoutを新しいプロセスと新しいスレッドに配置しているため、期待どおりに実行されます。
さらに複雑なのは、ハードウェアレベルであり、プロセスより多くのスレッドが実行されているため、コンテキストの切り替えにより、予想されるタイミングから(非常に小さな)遅延が発生します。これはごくわずかで、重要な場合は、何をしようとしているかを真剣に検討する必要があり、なぜそのような正確さが必要か、代わりにどのような種類のリアルタイムハードウェアが代わりに使用できるかを検討する必要があります。
一般に、子プロセスを使用し、ロードバランサーまたは共有データストレージ(redisなど)と一緒に複数のノードアプリケーションを個別のプロセスとして実行することは、コードをスケーリングするために重要です。
setTimeout
一種のThreadであり、一定時間操作を保持して実行します。
setTimeout(function,time_in_mills);
ここでは、最初の引数は関数型でなければなりません。例として、3秒後に名前を印刷する場合、コードは次のようになります。
setTimeout(function(){console.log('your name')},3000);
覚えておくべき重要な点は、setTimeout
メソッドを使用して何をしたい場合でも、関数内で実行することです。パラメータを解析して他のメソッドを呼び出す場合、コードは次のようになります。
setTimeout(function(){yourOtherMethod(parameter);},3000);