JavaScriptの人種状態の質問
-
12-09-2019 - |
質問
編集:ここに投稿した元のYui3の質問に対する答えを見つけましたが、それは別のものにつながり、新しいスレッドを始める代わりに、ここに追加するだけだと思いました。新しい質問については下にスクロールしてください(太字です)。
元の質問:YUI定義内にJavaScriptカウントダウンタイマーを作成するいくつかの問題があります。私の推測は、オブジェクトスコーピングと関係があります。これが私のコードです:
YUI({combine: true, timeout: 10000}).use("node", function (Y) {
var timer = new function(){};
Y.augment(timer, Y.EventTarget);
timer.on('timer:down', function() {
Y.log('timer down event fired', 'event');
Y.Lang.later(1000, Y, timer_trigger());
});
timer.on('timer:end', function() {
Y.log('timer end event fired', 'event');
});
var timer_from;
function startTimer(seconds){ // start a coundown from seconds to 0
timer_from = seconds;
timer_trigger();
}
function timer_display(){
var mins = Math.floor(timer_from/60);
var secs = timer_from - mins*60;
var secsDisp = secs;
if(secs<10){
secsDisp = '0' + secs;
}
Y.one('#timer').set('innerHTML', mins + ':' + secsDisp);
}
function timer_trigger(){
Y.log('timer from is: '+timer_from);
if(timer_from > 0){
timer_from--;
timer_display();
if(timer_from > 0){
timer.fire('timer:down');
}
} else {
timer.fire('timer:end');
}
}
function initializePage(){
startTimer(900);
}
});
私が得ているエラーは、私が電話するように頼んでいるように1000msを待たないということです timer_trigger()
そして、サファリは最終的に、コードの実行を停止したいかどうかを尋ねます。ページをロードしてから数秒後に行うと、タイマーはすでに約3、4分まで下がっています。私も使用しようとしました setTimeout
しかし、それは同じ結果も生成します。誰かが助けることができますか?とても感謝しております!
編集:私は実際に解決策を見つけました - これはたくさんのことを試してみましたが、さらにいくつかのGoogle検索が新しい結果/回答を生成することがあります(私は答えを見つけました このサイト, 、 実際に)。
どうやら私のコードは人種条件を作成していたようであり、それを修正するために私がしなければならなかったのはこれだけです:
setTimeout(function(){
timer_trigger();
}, 1000);
私は人種の条件を調べましたが、私の場合、それが何を意味するのか、そして私のコードの一見些細な変化が私が抱えていた問題をどのように修正したかは不明です。したがって、元の質問に答えましたが、これを答えから生じた質問に変えたいと思います。
JavaScriptのスレッドはどのように機能し、何が私の人種状態を引き起こし、なぜコードのマイナーな変更が私が持っていたエラーを修正したのですか?
解決
Also note that
Y.Lang.later(1000, Y, timer_trigger());
executes timer_trigger immediately and passes the return value to Y.Lang.later. You probably meant
Y.Lang.later(1000, Y, timer_trigger);
他のヒント
The problem is not a race condition. The reason the additional call to setTimeout "fixes" your code is because of a logic flaw in timer_trigger
. Consider what happens in the case where timer_from
is 1 when the function is called. Neither timer:down nor timer:end will be triggered.
function timer_trigger(){
Y.log('timer from is: '+timer_from);
if(timer_from > 0){ // Since timer_from is 1, the if block is entered
timer_from--; // timer_from is 0
timer_display();
if(timer_from > 0){ // This block is not entered, but it has no matching else
timer.fire('timer:down');
}
} else { // The matching if block was entered, so this is not
timer.fire('timer:end');
}
}
You added this code:
setTimeout(function(){
timer_trigger();
}, 1000);
This causes timer_trigger
to be called once more with timer_from
already set to 0, allowing the else block to be executed.