从延迟的回调中返回承诺

Returning a promise from within a deferred's callback

本文关键字:返回 承诺 回调 延迟      更新时间:2023-09-26

我正在做一些任何事情,我真的很想以良好的方式实现它。

请考虑以下代码

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,3秒后获取"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"消息。

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

这正是

.then()(或jQuery 1.8之前的.pipe()(所做的。

称之为而不是.done().

你不能从回调中return任何东西,因为这毫无意义 - 结果不会在调用方的任何地方使用,它的类型实际上是void的。

要链接操作,您可以使用 then 而不是 done 。该方法将为回调的(异步(结果返回一个承诺,该结果本身可以是一个承诺。