0

我正在研究一些 anync 的东西,我真的很想以一种好的方式实现它。

考虑以下代码

function getData(latency) {
    var deferred = $.Deferred();

    window.setTimeout(function () {
        deferred.resolve(Math.random());
    }, latency + 100);

    return deferred.promise();
}
function getSpecialData() {
    var deferreds = [];
    for (var i = 0; i < 3; i++) {
        deferreds.push(getData(1000 * i));
    }
    return $.when.apply($, deferreds);
}

function log(msg) {
    $("#console").append("<li>" + msg + "</li>");
    console.log(msg);
}

getData(3000)
.done(function () {
    log("got 3000 data");
    return getSpecialData()
    .done(function () {
        log("got special data");
    });
})
.always(function () {
    log("got all data");
});

如您所见,我从 getData 和 getSpecialData 函数中返回了一个承诺。我还以您看到的方式链接对这些函数的调用。更重要的是,我从 getData done 回调中返回了一个承诺。

我一直期待延迟对象关心它的回调返回什么,如果它是一个承诺,请等待该承诺解决,然后再进行另一个回调。实际发生的是它不关心我从回调中返回的内容。顺序是:

  1. 调用getData,3s后获取"got 3000 data"信息,
  2. 同时触发 getSpecialData 和带有消息的always回调"got all data"

我想要实现的是以下函数调用顺序:

  1. 调用getData,3s后获取"got 3000 data"信息,
  2. 调用getSpecialData,3s后获取"got special data"信息,
  3. 消息后立即"got all data"

使它按我想要的方式工作的最佳方法是什么?

4

2 回答 2

1

这正是.then()(或.pipe()在 jQuery 1.8 之前)所做的。

调用它而不是.done().

于 2013-10-11T14:07:48.167 回答
0

你不能return从回调中得到任何东西,因为那是没有意义的——结果没有在调用者的任何地方使用,它的类型是有效的void

要链接操作,您可以使用then代替done. 该方法将为回调的(异步)结果返回一个 Promise,它本身可以是一个 Promise。

于 2013-10-11T14:11:12.293 回答