关于javascript:deferred.fail()之后如何继续执行JS

How to continue executing JS after deferred.fail()

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

如果我们使用.fail(),似乎一切都将停止执行。我们需要继续验证功能。我找到了这个问题/答案,但似乎没有什么不同:延后一次失败后,是否有继续的方法?

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

1
2
3
4
5
6
7
8
9
10
11
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];
        });
    }
});


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

  • 不要使用.fail,请使用.then
  • 返回失败后解决的问题。

这就像发出信号,表明我们已经处理了我们在这里得到的异常:

1
2
3
4
5
6
7
8
9
10
11
12
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
});

这将使您能够做到:

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


无论是由Backbone的validate()中的函数还是由validate()本身返回的,我们都无法兑现Promise。但是我在Backbone内部发现了一个解决方案-save()将接受async: false并暂停执行直到收到响应,然后从那里继续。它可能在后台使用了一个诺言。

1
2
3
4
5
6
7
8
9
10
11
12
13
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];
            });
        }
    }
});