Notifier une fois la tâche asynchrone terminée

Je construis un jeu avec move.js pour l’animation, mais cela prend trop de temps. Lorsque le joueur clique sur la bonne solution, il affiche le message gagnant avant que la bonne solution ne change de couleur. J’ai donc utilisé un object différé pour déclencher un événement. attrapez-le quand l’animation se termine.

Voici mon code:

 var deferred = new $.Deferred(); click(e); //show message when game is over $.when(deferred).then(function(){ if (this.checkIfWin()){ alert('you won !'); this.nextLevel(); } }); function click(e){ move(e) .set('background-color','black') .delay('0.1s') .end(); deferred.notify(); } 

mais ce n’est pas notifié et le message ne s’affiche pas. Qu’est-ce qui me manque ici?

Comme les animations en javascript sont asynchrones (elles s’exécutent via des timers), le seul moyen de savoir quand elles sont terminées est de se connecter à une sorte de rappel d’achèvement ou de notification d’achèvement.

Je ne connais pas move.js moi-même, mais il semble que vous puissiez obtenir un tel rappel en fournissant un rappel à la .end(fn) . Mais vous devrez également corriger votre code car this dans this.checkIfWin() ne sera pas la bonne valeur dans aucun de ces blocs de code. Je ne sais pas ce que vous voulez qu’il soit (puisque vous ne montrez pas cette partie de votre code), mais vous devrez vous référer à un autre object en plus de this . Dans tous les cas, voici la structure générale du code avec et sans utilisation d’un code différé.

 var deferred = new $.Deferred(); // your code was using this here // so I will save a reference to it that can be used later, but there is // probably a better way to do this if I could see the rest of your code var obj = this; click(e); //show message when game is over deferred.promise().then(function(){ if (obj.checkIfWin()){ alert('you won !'); obj.nextLevel(); } }); function click(e){ move(e) .set('background-color','black') .delay('0.1s') .end(function() { deferred.resolve(); }); } 

Dans ce cas, il ne semble pas que vous ayez vraiment besoin d’utiliser le différé, car vous pouvez simplement insérer le code d’achèvement dans le rappel:

 // your code was using this here // so I will save a reference to it that can be used later, but there is // probably a better way to do this if I could see the rest of your code var obj = this; click(e); function click(e){ move(e) .set('background-color','black') .delay('0.1s') .end(function() { if (obj.checkIfWin()){ alert('you won !'); obj.nextLevel(); } }); } 

Édition, fonction de rappel ajoutée à .end() pour inclure deferred.notify . Voir les commentaires, Déplacer # end ([fn])

Essayer

 var deferred = new $.Deferred(); click(e); // `e` undefined ? deferred.progress(function(msg) { // `this` within `deferred` // references `deferred` object , // try `obj.checkWin()`, `obj.nextLevel()` if (obj.checkWin()) { alert(msg); obj.nextLevel(); } }); function click(e) { // `e` undefined ? move(e) .set('background-color','black') // `.delay()` accepts `number` as argument ? .delay('0.1s') // see comments , // http://visionmedia.github.io/move.js/#example-11 .end(function() { deferred.notify("you won !"); }); }; 

jsfiddle http://jsfiddle.net/guest271314/4Av4Z/