Frage

Bearbeiten: Ich habe die Antwort auf die ursprüngliche Yui3 -Frage herausgefunden, die ich hier gepostet habe, aber sie führte zu einem anderen und anstatt einen neuen Thread zu starten, dachte ich, ich würde ihn hier einfach hinzufügen. Bitte scrollen Sie nach unten für die neue Frage (sie ist mutig).

Originalfrage: Ich habe einige Probleme beim Erstellen eines JavaScript -Countdown -Timers in einer YUI -Definition. Meine Vermutung ist etwas mit dem Objekt Scoping zu tun. Hier ist mein Code:

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


});

Der Fehler, den ich bekomme, ist, dass es die 1000 ms nicht wartet timer_trigger() Und Safari fragt mich schließlich, ob ich aufhören möchte, den Code auszuführen. Wenn ich ein paar Sekunden nach dem Laden der Seite mache, ist der Timer bereits auf etwa 3, 4 Minuten gesunken. Ich habe auch versucht zu benutzen setTimeout Das erzielt aber auch das gleiche Ergebnis. Kann jemand helfen? Ich würde es wirklich schätzen!

Bearbeiten: Ich habe tatsächlich eine Lösung herausgefunden - dies geschah nach Stunden, um Tonnen von Dingen auszuprobieren, aber ein paar weitere Google -Suchanfragen können manchmal immer noch neue Ergebnisse/Antworten erzielen (ich fand die Antwort auf Diese Seite, eigentlich).

Anscheinend erstellte mein Code also eine Rennbedingung, und alles, was ich tun musste, um dies zu beheben, ist Folgendes:

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

Ich habe die Rassenbedingungen nachgeschlagen, aber es ist unklar, was es in meinem Fall bedeutet und wie die scheinbar triviale Änderung in meinem Code das Problem behoben hat, das ich hatte. Die ursprüngliche Frage wurde also beantwortet, aber ich möchte dies in die Frage verwandeln, die sich aus der Antwort ergibt.

Wie funktioniert das Threading in JavaScript und was verursachte meine Rennbedingung und warum hat sich die geringfügige Änderung des Codes den Fehler festgestellt, den ich hatte?

War es hilfreich?

Lösung

Beachten Sie auch das

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

Fügt Timer_trigger sofort aus und übergibt den Rückgabewert an y.lang.later. Sie haben wahrscheinlich gemeint

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

Andere Tipps

Das Problem ist keine Rennbedingung. Der Grund, warum der zusätzliche Anruf bei SetTimeout Ihren Code "behebt", liegt in einem logischen Fehler in timer_trigger. Überlegen Sie, was in dem Fall passiert, wo timer_from ist 1, wenn die Funktion aufgerufen wird. Weder Timer: Down noch Timer: Das Ende wird ausgelöst.

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

Sie haben diesen Code hinzugefügt:

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

Dies bewirkt timer_trigger noch einmal aufgerufen werden mit timer_from Bereits auf 0 gesetzt, sodass der else -block ausgeführt werden kann.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top