これは本当に簡単な質問です。を使用する場合setInterval(something, 1000)
、たとえば31日後に、正確に「何か」がトリガーされることを完全に確信でき60*60*24*31
ますか?または、いわゆるドリフトのリスクはありますか?
3 に答える
簡単な答え:いいえ、確信が持てません。はい、ドリフトする可能性があります。
長い答え:JavaScript時間の精度とJavaScriptタイマーのしくみについてのJohnResig 。
2番目の記事から:
タイマーが内部でどのように機能するかを理解するために、調査する必要のある重要な概念が1つあります。それは、タイマーの遅延が保証されていないということです。ブラウザのすべてのJavaScriptはシングルスレッドで実行されるため、非同期イベント(マウスクリックやタイマーなど)は、実行が開始されたときにのみ実行されます。
両方の記事(およびそのサイトのすべてのもの)は素晴らしい読み物ですので、それを読んでください。
Firefoxで実行できるベンチマークは次のとおりです。
var start = +new Date();
var count = 0;
setInterval(function () {
console.log((new Date() - start) % 1000,
++count,
Math.round((new Date() - start)/1000))
}, 1000);
最初の値は、可能な限り0または1000に近づける必要があります(他の値は、トリガーのタイミングが「オフスポット」であったことを示します)。2番目の値は、コードがトリガーされた回数であり、3番目の値は回数です。トリガーされるべきでした。CPUを停止すると、その場からかなり外れる可能性がありますが、それ自体は修正されているようです。長時間実行して、どのように処理されるかを確認してください。
(私の悪い英語について申し訳ありません)私は関数のカウントダウンについて同じ問題を抱えていました、私は関数countdown()とsetIntervalでループを書きましたが、ループごとに1〜3ミリ秒ドリフトします。それから私はドリフトがあるかどうかを制御する関数を書き、それを修正しました。
それは実際の分と秒だけで制御します。ここにあります。それは私にはうまく機能します、私はそれがあなたにも役立つことを願っています。
$.syncInterval(functionname,interval,controlinterval)
例:
countdown(){ some code };
$.syncInterval(countdown,1000,60);
1000ミリ秒ごとにカウントダウン機能を実行し、60秒ごとにチェックすると書かれています
コードは次のとおりです。
$.syncInterval = function (func,interval,control) {
var
now=new Date();
realMinute=now.getMinutes(),
realSecond=now.getSeconds(),
nowSecond=realSecond,
nowMinute=realMinute,
minuteError=0,
countingVar=1,
totalDiff=0;
var loopthat = setInterval(function(){
if (nowSecond==0) {
nowMinute++;
nowMinute=nowMinute%60;
};
if (countingVar==0){
now=new Date();
realSecond=now.getSeconds();
realMinute=now.getMinutes();
totalDiff=((realMinute*60)+(realSecond))-((nowMinute*60)+(nowSecond));
if(totalDiff>0){
for (i=1;i<=totalDiff;i++) {
func();
nowSecond++;
countingVar++;
};
} else if (totalDiff==0){
func();
nowSecond++;
countingVar++;
} else if (totalDiff<0) {
};
} else {
func();
nowSecond++;
countingVar++;
};
countingVar=countingVar%control;
nowSecond=nowSecond%60;
},interval);
};