【问题标题】:How to handle returning a promise when one is already running?当一个已经运行时如何处理返回一个承诺?
【发布时间】:2016-09-01 17:50:15
【问题描述】:

我有一个 javascript 类,它当前进行一些异步调用,将元素添加到 DOM,然后调用用户回调。像这样的:

api.load = function() {
    if (api.loading || api.loaded)
        return;

    api.loading = true;
    makeAsyncCalls(); // will set api.loaded = true and run all pendingReady
}

api.ready = function(callback) {
    if (!api.loaded) {
        pendingReady.push(callback);
    }
    callback(someValue);
}

这让我可以处理对loadready 的多个调用。

我现在正在尝试更新它以使用 javascripts Promise。上面的代码会变成这样:

api.load = function() {
    if (api.loaded) {
        // callers attached .then() will still fire
        return Promise.resolve(someValue);
    }

    if (api.loading) {
        // Not sure how to handle this
    }

    api.loading = true;
    return makeAsyncCalls(); // Which returns a Promise
}

我不知道如何处理第一个 Promise 已启动但尚未完全加载的情况(在 promise 演讲中解决)。我能想到的唯一方法是返回一个包含对setInterval 检查状态的调用的 Promise。当然有更好的方法。有什么建议吗?

为了更清楚地说明这一点。对api.load 的每次调用都必须返回Promisethenable。第一次调用将启动异步方法。进一步的调用需要返回一个 Promise,它只能在初始的 Promise 完成后解决或拒绝。

只有在没有向成功处理程序传递任何值的情况下,链式 Promise 才会起作用(第一个 .then() 可能不会返回相同的值)。

【问题讨论】:

    标签: javascript asynchronous promise queue


    【解决方案1】:

    promise 本身可以替代异步接收的数据...

    api.getAsyncResult = function() {
        if (!api.asyncResult) {
            api.asyncResult = makeAsyncCalls();
        }
        return api.asyncResult;
    }
    

    现在任何时候任何数量的呼叫者都可以说:

    api.getAsyncResult().then(function(result) {
        // use result, which is whatever makeAsyncCalls's promise resolves to
    });
    

    第一次调用将启动异步工作。随后的调用(使用相同的形式)会将thens 链接到返回的承诺。在 Promise 完成之后,它将继续将其解析值作为参数传递给传递给 then() 的函数

    makeAsyncCalls() 函数可以根据需要维护api.loading 标志的状态。如果api.loaded 标志的唯一目的是防止冗余调用(get 函数中的错误检查就是这样做的),则不需要api.loaded

    【讨论】:

    • 我花了几次,但我想我明白了。如果我错了,请纠正我(我一直在考虑then)。一旦初始的Promise 得到解决,它就会保持该状态,因此对then 的任何调用都会自动调用成功处理程序,并带有asyncResult?我只需要保留并返回它的本地副本。
    • 你有它。它将使用 makeAsyncCalls 承诺解析为的任何内容调用成功处理程序。
    • 不,这是关于承诺的不太常见的事情。它们不仅控制异步流,还可以用作名词、尚未可用数据的占位符。
    猜你喜欢
    • 1970-01-01
    • 2015-11-27
    • 2017-12-26
    • 1970-01-01
    • 2017-05-09
    • 2015-06-05
    • 1970-01-01
    • 1970-01-01
    • 2020-04-27
    相关资源
    最近更新 更多