异步任务完成后通知

时间:2014-07-26 13:47:56

标签: javascript jquery jquery-deferred

我正在使用move.js构建一个用于动画的游戏,但这需要太长时间,所以当玩家点击正确的解决方案时,它会在正确的解决方案改变它的颜色之前显示获胜的消息,所以我使用延迟对象来触发事件并在动画结束时捕获它。

这是我的代码:

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

但是没有收到通知,但邮件没有显示出来。我在这里错过了什么?

2 个答案:

答案 0 :(得分:1)

因为javascript中的动画是异步的(它们通过计时器运行),所以知道它们何时完成的唯一方法是挂钩某种完成回调或完成通知。

我自己并不了解move.js,但看起来你可以通过提供.end(fn)方法的回调来获得这样的回调。但是,您还必须修复代码,因为this中的this.checkIfWin()在这些代码块中都不是正确的值。我不知道你想要它是什么(因为你没有显示你的部分代码),但你必须引用this以外的其他一些对象。无论如何,这里是使用和不使用延迟的代码的一般结构。

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

在这种情况下,看起来您确实需要使用延迟,因为您可以将完成代码放在回调中:

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

答案 1 :(得分:0)

编辑,向.end()添加回调功能以包含deferred.notify。请参阅评论,Move#end([fn])

尝试

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/