多个调用者可以使用 Babel await 关键字订阅同一个异步函数吗?

Can multiple callers subscribe to the same async function, using the Babel await keyword?

如果 returns CommonJS 承诺,多个调用者可以订阅正在进行的函数:

let curWaitTask;
let lastWaitTime = new Date(1970, 0, 1);
let func1 = function() {
  if(curWaitTask) {
    return curWaitTask;
  }
  if((new Date() - lastWaitTime) > TWENTY_MINUTES) {
    lastWaitTime = new Date();
    curWaitTask = func2().then(func3).then(func4);
    return curWaitTask;
  }
}

以上是缓存过期的做法。在 20 分钟缓存过期后第一次调用 func1 将导致服务执行另一个异步操作来更新缓存。与此同时,可能会发生对 func1 的其他调用,这将等待相同的缓存更新操作,而不是一次又一次地发生,直到缓存被设置(由于所有调用,连续多次)。

有没有什么方法可以在使用 Babel await 关键字而不是一串笨拙的 .then() 关键字提供的清晰度的同时获得这种行为?在实践中,它变得丑陋。

只需将 "unwieldy then chain" 包裹在 async function 中并在其中使用 await

let curWaitTask;
let lastWaitTime = new Date(1970, 0, 1);
function func1() {
  if (!curWaitTask && (new Date() - lastWaitTime) > TWENTY_MINUTES) {
    lastWaitTime = new Date();
    curWaitTask = doTask();
  }
  return curWaitTask;
}
async function doTask() {
  return func4(await func3(await func2()));
}

(幸运的是?)不可能在 async function 中引用从当前调用创建的新承诺,因此在这里使用 async function func1 并不是很明智。

你询问是否多个调用者可以订阅同一个 async 函数,所以让我们看看我们是否可以在 func1 内解决这个问题并保持异步(在来自的帮助下贝尔吉!):

let curTask;
let lastTime = new Date(1970, 0, 1);

async function func1() {
  if (curTask && (new Date() - lastTime) < 10000) {
    return await curTask;
  }
  return await (curTask = (async () => {
    lastTime = new Date();
    return await func4(await func3(await func2()));
  })());
}

我们可以等待 promises,而不仅仅是异步函数。

我们将工作的重点放在我们不立即等待的第二个异步函数中,从而获得它的承诺,我们用同步初始化 curTask