Question

EDIT: Je me suis dit la réponse à la question YUI3 originale que j'ai posté ici, mais il conduit à un autre et au lieu de commencer un nouveau thread, je pensais que je venais de l'ajouter ici. S'il vous plaît défiler vers le bas pour la nouvelle question (il est mis en gras).

question d'origine: Je vais avoir quelques problèmes en créant un compte à rebours JavaScript dans une définition de YUI, je suppose quelque chose à voir avec portée de l'objet. Voici mon 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);
    }


});

L'erreur que je reçois est qu'il n'attend pas les 1000ms comme je demande à appeler timer_trigger() et Safari me demande finalement si je veux arrêter l'exécution du code. Quand je fais quelques secondes après le chargement de la page, la minuterie est déjà en baisse à environ 3 à 4 minutes. J'ai aussi essayé d'utiliser setTimeout mais qui produit aussi le même résultat. Quelqu'un peut-il aider? Je voudrais vraiment l'apprécier!

EDIT: En fait, je pensais trouver une solution - cela est venu après les heures d'essayer des tonnes de choses, mais quelques autres recherches Google peut parfois produire encore de nouveaux résultats / réponses (j'ai trouvé la réponse sur ce site , en fait).

Donc, apparemment, mon code a été crée une condition de course, et tout ce que je devais faire pour y remédier est la suivante:

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

J'ai regardé les conditions de course, mais il est clair pour moi ce que cela signifie dans mon cas, et comment le changement apparemment trivial à mon code fixe la question que je faisais. Donc, la question initiale en réponse, mais je voudrais transformer cela en la question qui se pose de la réponse.

Comment le filetage dans le travail JavaScript et que la cause de mon état de course, et pourquoi le changement mineur dans le code corriger l'erreur que j'avais?

Était-ce utile?

La solution

Notez également que

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

exécute immédiatement timer_trigger et transmet la valeur de retour à Y.Lang.later. Vous avez probablement voulu dire

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

Autres conseils

Le problème est pas une condition de course. La raison pour laquelle l'appel supplémentaire à setTimeout « fixe » votre code est en raison d'un défaut de logique dans timer_trigger. Pensez à ce qui se passe dans le cas où timer_from est 1 lorsque la fonction est appelée. Ni la minuterie: vers le bas, ni minuterie. Fin sera déclenchée

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

Vous avez ajouté ce code:

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

Cela provoque timer_trigger à appeler une fois de plus avec timer_from déjà mis à 0, ce qui permet au bloc d'autre à exécuter.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top