jQuery延迟对象链接失败

jQuery deferred object chaining failing

本文关键字:失败 链接 对象 延迟 jQuery      更新时间:2023-09-26

为什么这段代码不能工作?

在加载步骤2之前应该等待步骤1加载完成。目前,第2步首先触发。我使用mockjax来模拟Ajax调用。

$.mockjax({
    url: "/step1",
    responseTime: [3000, 4000],
    responseText: {
      status: "success",
      text: "Loading Step 1"
    }
});
$.mockjax({
    url: "/step2",
    responseTime: [100, 200],
    responseText: {
      status: "success",
      text: "Loading step 2"
    }
});

$.getJSON("/step1").then( function(response) {
    return  $("#message").html( "message: " + response.text );
})
.then(
    $.getJSON("/step2", function(response) {
            $("#message").html( "message: " + response.text );
    })                
)

getJSON step2首先触发,因为它具有较短的延迟,并且您可以有效地触发两个$。getJSON的同时

试试这个

$.getJSON("/step1").then( function(response) {
    return  $("#message").html( "message: " + response.text );
})
.then(
    function() { // added this
        $.getJSON("/step2", function(response) {
            $("#message").html( "message: " + response.text );
        })         
    } // and added this
)

公认的答案不太正确。它并没有真正链接承诺,因为这个:

$("#message").html( "message: " + response.text )

是一个同步函数,不返回promise。因此,返回它返回的值不会创建承诺链。它在这个例子中是有效的,但是当你添加越来越多的承诺时,你会遇到麻烦。

链接承诺的正确方法是返回一个承诺:

someFunction().then(function(){return promise}).then(function(){});

对于你的例子,正确的链接方式是:

$.getJSON("/step1")
.then( function(response) {
    $("#message").html( "message: " + response.text );
    return $.getJSON("/step2"); // <-------------- return a promise!
})
.then(function(response){
    $("#message").html( "message: " + response.text );
})

UPDATE:根据注释,$.when()在这里是不必要的,应该在合并多个promise时使用。

我建议在这里看看使用when - jsFiddle的例子。

    $.mockjax({
    url: "/step1",
    responseTime: [3000, 4000],
    responseText: {
      status: "success",
      text: "Loading Step 1"
    }
});
$.mockjax({
    url: "/step2",
    responseTime: [100, 200],
    responseText: {
      status: "success",
      text: "Loading step 2"
    }
});

$.when($.getJSON("/step1"))
    .then( function(data, textStatus, jqXHR) {
        $("#message").html( "message: " + data.text );
    })
    .then(
        $.getJSON("/step2", function(data, textStatus, jqXHR) {
            $("#message").html( "message: " + data.text );
    })                
)