jQuery Deferred:拒绝完成过滤器中的承诺

Aje*_*i32 23 jquery jquery-deferred

Fyi,我刚刚开始学习jQuery的承诺,所以我在这里可能有点困惑.

无论如何,我有一个AJAX请求,我想根据响应的内容在完成过滤器中拒绝:

return doAJAXRequest().then(function (data) {
    if (data.responseText == "YES") {
        return doOtherAJAXRequest();
    } else {
        this.reject(data);
    }
});
Run Code Online (Sandbox Code Playgroud)

这不像我预期的那样有效:

Uncaught TypeError: Object #<Object> has no method 'reject'
Run Code Online (Sandbox Code Playgroud)

我如何根据其响应使此承诺失败?那可能吗?或者我只是对这里需要做什么感到困惑?

Bee*_*oot 34

在jQuery中(与其他一些lib不同),将一个从"已解决"状态转换为"被拒绝"状态的承诺略显冗长,需要显式创建和拒绝新的Deferred.

function foo() {
    return doAJAXRequest().then(function (data, textStatus, jqXHR) {
        if (data.responseText == "YES") {
            return doOtherAJAXRequest(data);
        } else {
            return $.Deferred().reject(jqXHR, data, 'Not YES').promise();
        }
    });
)
Run Code Online (Sandbox Code Playgroud)

在这里,如果data.responseText !== "YES"模仿(部分)失败的ajax请求,同时仍允许data传递,则返回promise .这对于下游.fail()处理程序来说(可能)很重要,下游处理程序必须处理真正的ajax故障和transmogrified成功条件,而不知道在读取之前发生了哪一个errorThrown.

foo().fail(function(jqXHR, textStatus, errorThrown) {
    if(errorThrown == 'Not YES') {
        //transmogrified success
        var data = textStatus;
        ...
    }
    else {
        //genuine ajax failure
        ...
    }
}); 
Run Code Online (Sandbox Code Playgroud)

通常以data这种方式传递更容易,而不是从jqXHR对象重新获取它.对于JSON编码数据尤其如此,否则需要在失败处理程序中第二次解码.

  • 我认为promise()部分不需要(或不再需要),这使得调用不那么丑陋/冗长. (2认同)