2

我正在为演示准备一些示例材料,其中还涵盖了 jQuery 承诺的基础知识,并且我正在计算一些奇怪的行为。希望你们能帮我解决这个问题。

我有以下代码可以正常工作。

var getHTML1 = $.ajax({
        url: "jquerypromises.html",    
        type: "GET"
});

getHTML1.done(function(responseText, state, jqXHR){
    console.log("success from AJAX request with promises : getHTML1!");
});

getHTML1.fail(function(){
    console.log("error from AJAX request with promises : getHTML1!");
});

//this one will call the failure callback!!!!!!
var getHTML2 = 
$.ajax({
        url: "somenonexistingpage.html", //<== THIS WILL call the failure callback   
        type: "GET"
})
.then(
    function(){
        console.log("success from AJAX request with promises : getHTML2!");
    }
, 
    function(jqXHR, state){
        console.log("error from AJAX request with promises : getHTML2!");
    }
);

此代码按照调用getHTML1完成处理程序和调用getHTML2失败处理程序的预期运行。

现在,当我在上面看到的代码下方添加以下代码时。

$.when(getHTML1, getHTML2).then(
    function(response1, response2) {
        // both arguments are arrays with[responseText, "success", jqXHR] 
        console.log("Both promises went successfull");
        console.dir(response1);
        console.dir(response2);
    },
    function(jqXHR, status) {   
        console.log("One of both promises went wrong!");        
        console.log(jqXHR);
        console.log(status);        
    }   
);

再次调用适当的处理程序。在这种情况下,正在调用失败回调,但它的所有参数都是未定义的。为什么是这样?

现在,当我删除块中的失败处理程序时,then()代码getHTML2变成这样:

var getHTML2 = 
$.ajax({
        url: "somenonexistingpage.html", //<== THIS WILL call the failure callback   
        type: "GET"
})
.then(
    function(){
        console.log("success from AJAX request with promises : getHTML2!");
    }
);

现在一切都像预期的那样工作,第二个 then() 块中的失败处理程序被调用并填充了参数。

使用 jQuery 1.9.1 在 Chrome 中测试

4

1 回答 1

0

基本上,那是因为then()的文档说(强调我的):

这些过滤器函数可以返回一个新值以传递给Promise.done().fail()回调,或者它们可以返回另一个可观察对象(Deferred、Promise 等),它将其已解决/拒绝状态和值传递给 Promise 的回调。如果使用的过滤器函数是null或未指定,则承诺将被解析或拒绝,并使用与原始相同的值

因此,您可以从失败过滤器返回单个值,这不是您想要的(您想要两个值),或者完全省略失败过滤器以then()传递与原始承诺相同的值。

如果你想实现一个返回多个值的失败过滤器,你可以返回一个新的 Deferred 对象,你立即用这些值拒绝它:

var getHTML2 = $.ajax({
    url: "somenonexistingpage.html", //<== THIS WILL call the failure callback   
    type: "GET"
}).then(function() {
    console.log("success from AJAX request with promises : getHTML2!");
}, function(jqXHR, state) {
    console.log("error from AJAX request with promises : getHTML2!");
    return $.Deferred().reject(jqXHR, state);
});
于 2013-02-18T15:42:06.893 回答