【问题标题】:Make concurrent await calls for the same promise wait for the first call to fulfill only once对同一个 Promise 进行并发 await 调用,只等待第一个调用完成一次
【发布时间】:2020-07-02 03:24:02
【问题描述】:

我正在尝试完全解决 this problem 但在 ES2020 中。

假设我有一个承诺会在一秒钟后解决,并且该承诺有几个awaits,从不同的地方同时调用。承诺只能解决一次,awaits 应该返回它的结果。在下面的代码中,我希望所有调用者都得到1

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

let counter = 0;
async function getSomething() {
  await sleep(1000);
  return ++counter;
}

(async function caller1() {
  console.log(await getSomething());
})();

(async function caller2() {
  console.log(await getSomething());
})();

(async function caller3() {
  console.log(await getSomething());
})();

我该怎么做?

【问题讨论】:

  • 问题是函数getSomething 每次被调用时都会返回一个新的promise,所以你的每个调用函数都在等待单独的函数。您可以执行类似const something = getSomething(); (async function caller1() { console.log(await something); })(); (async function caller2() { console.log(await something); })();caller2 之类的操作,最终会评估与caller1 相同的Promise。

标签: javascript


【解决方案1】:

最简单的模式是利用 Promise 只结算一次的事实,像这样重写getSomething

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

let counter = 0;
let promise;
async function getSomething() {
  // If another invocation has already initialized the promise, return that promise
  if (promise)
    return promise;
  // Otherwise, we're the first invocation, so initialize the promise...
  promise = sleep(1000).then(() => ++counter);
  // ...and return it
  return promise;
}

(async function caller1() {
  console.log(await getSomething());
})();

(async function caller2() {
  console.log(await getSomething());
})();

(async function caller3() {
  console.log(await getSomething());
})();

【讨论】:

    猜你喜欢
    • 2021-03-10
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-09
    • 2012-08-27
    相关资源
    最近更新 更多