如何在deferred.fail()之后继续执行JS

时间:2015-04-08 22:12:02

标签: javascript jquery backbone.js promise jquery-deferred

下面是一些采用Backbone模型的代码,保存它然后等待响应并触发jQuery .done()或.fail()代码。这工作正常,但是如果失败,我们实际上希望从服务中获取返回的消息,将其添加到我们的errors对象中。这都在Backbone validate()函数中;在此代码之后,我们检查errors对象并显示消息(如果有)。

似乎我们.fail(),一切都停止执行。我们需要继续验证功能。我找到了这个问题/答案,但它似乎没有什么区别:Is there a way to continue after one deferred fails?

在点击deferred.fail()之后继续执行代码的任何方法?

addressModel.save().done(function() {
    console.log("promise done");
    model.set("...", false);
}).fail(function(response) {
    console.log("promise fail");
    if (response.responseJSON && response.responseJSON._messages) {
        _.each(response.responseJSON._messages, function(value, key) {
            errors[key] = value[0];
        });
    }
});

2 个答案:

答案 0 :(得分:1)

这可能但很棘手 - 至少到3.0。诀窍是:

  • 请勿使用.fail使用.then
  • 从失败中返回已解决的延迟。

这就像发信号通知我们处理了我们在这里得到的例外:

var p = addressModel.save().then(function() {
    console.log("promise done");
    model.set("...", false);
}, function(response) {
    console.log("promise fail");
    if (response.responseJSON && response.responseJSON._messages) {
        _.each(response.responseJSON._messages, function(value, key) {
            errors[key] = value[0];
        });
    }
     return $.Deferred().resolve(); // return a resolved deferred
});

这将允许你这样做:

p.then(function(){
  // this code runs when either failure or success happened, can also chain
});

答案 1 :(得分:0)

我们永远无法使用承诺,无论是由Backbone的validate()中的函数还是validate()本身返回的。但我在Backbone本身找到了一个解决方案 - save()将接受async: false并停止执行,直到收到响应,然后从那里继续。它可能会使用承诺在幕后执行此操作。

addressModel.save(null, {
    async: false,
    success: function() {
        model.set("...", false);
    },
    error: function(model, response) {
        if (response.responseJSON && response.responseJSON._messages) {
            _.each(response.responseJSON._messages, function(value, key) {
                errors[key] = value[0];
            });
        }
    }
});