Domanda

EDIT: ho capito la risposta alla domanda iniziale YUI3 ho postato qui, ma ha portato a un altro e invece di iniziare un nuovo thread ho pensato solo aggiungere qui. Si prega di scorrere verso il basso per la nuova domanda (è in grassetto).

domanda originale: Sto avendo alcuni problemi che creano un conto alla rovescia JavaScript all'interno della definizione di YUI, la mia ipotesi è qualcosa a che fare con l'oggetto di scoping. Ecco il mio codice:

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


});

L'errore che sto ottenendo è che non aspetta i 1000 ms come sto chiedendo di chiamare timer_trigger() e Safari alla fine mi chiede se voglio fermare l'esecuzione del codice. Quando faccio un paio di secondi dopo il caricamento della pagina, il timer è già verso il basso per circa 3, 4 minuti. Ho anche provato ad utilizzare setTimeout ma che produce anche lo stesso risultato. Chiunque può aiutare? Vorrei davvero apprezzare!

EDIT: Io in realtà capito una soluzione - questo è venuto dopo ore di tentativi tonnellate di cose, ma un paio di ricerche su Google a volte può ancora produrre nuovi risultati / risposte (ho trovato la risposta su questo sito , in realtà).

Quindi, a quanto pare il mio codice stava creando una condizione di competizione, e tutto quello che dovevo fare per risolvere il problema è questo:

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

Ho guardato condizioni di gara, ma non è chiaro per me che cosa significa nel mio caso, e come il cambiamento apparentemente banale al mio codice risolto il problema che stavo avendo. Quindi la domanda originale ha risposto, ma mi piacerebbe trasformare questo nella domanda che nasce dalla risposta.

Come funziona threading nel lavoro JavaScript e ciò che causare la mia condizione di competizione, e perché la piccola modifica nel codice di correggere l'errore che ho avuto?

È stato utile?

Soluzione

Si noti inoltre che

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

esegue timer_trigger immediatamente e passa il valore restituito al Y.Lang.later. Probabilmente dire

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

Altri suggerimenti

Il problema non è una condizione di competizione. Il motivo per cui la chiamata aggiuntiva a setTimeout "corregge" il codice è a causa di un difetto di logica in timer_trigger. Considerare cosa accade nel caso in cui timer_from è 1 quando viene chiamata la funzione. Nessuno dei due timer: giù né il timer:. Fine verrà attivato

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

Hai aggiunto questo codice:

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

Ciò causa timer_trigger essere chiamato ancora una volta con timer_from già impostato a 0, permettendo al blocco else da eseguire.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top