1


0

Javascriptの競合状態の質問

編集:ここに投稿した元の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);
    }


});

私が得ているエラーは、「timer_trigger()」を呼び出すように要求しているように1000ミリ秒待機しないことであり、Safariは最終的にコードの実行を停止するかどうかを尋ねます。 ページをロードしてから数秒すると、タイマーはすでに約3、4分になります。 また、 `setTimeout`を使用してみましたが、同じ結果が得られます。 誰も手伝ってくれる? とても感謝しております!

編集:私は実際に解決策を見つけました-これは何時間ものことを試してから来ましたが、さらにいくつかのGoogle検索はまだ新しい結果/回答を生成することがあります(私はhttps://stackoverflow.com/questions/1664951で答えを見つけました/ jquery-getjson-inside-settimeout-timer [このサイト]、実際)。

だから明らかに私のコードは競合状態を作り出していたので、それを修正するために私がしなければならなかったのはこれだけです:

setTimeout(function(){
    timer_trigger();
}, 1000);

競合状態を調べましたが、私の場合の意味と、コードに対する一見些細な変更がどのように私が抱えていた問題を解決したかはわかりません。 元の質問に答えましたが、これを答えから生じた質問に変えたいと思います。

  • JavaScriptのスレッド化はどのように機能し、競合状態の原因は何ですか?また、コードの小さな変更によりエラーが修正されたのはなぜですか?*

2 Answer


3


問題は競合状態ではありません。 setTimeoutへの追加の呼び出しがコードを「修正」する理由は、 `timer_trigger`の論理的な欠陥のためです。 関数が呼び出されたときに `timer_from`が1の場合に何が起こるか考えてください。 timer:downもtimer:endもトリガーされません。

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');
    }
}

このコードを追加しました:

setTimeout(function(){
    timer_trigger();
}, 1000);

これにより、 timer_from`がすでに0に設定された状態で timer_trigger`がもう一度呼び出され、elseブロックを実行できるようになります。


2


また注意してください

Y.Lang.later(1000, Y, timer_trigger());

timer_triggerをすぐに実行し、戻り値をY.Lang.laterに渡します。 あなたはおそらく意味した

Y.Lang.later(1000, Y, timer_trigger);