在多个位置等待异步函数

6

使用 Promises,我可以有两个独立的“线程”,都在等待同一个值:

let trigger;
const promise = new Promise(r => {
  console.log('promise is created *once*');
  trigger = value => {
    console.log('trigger is called *once*');
    r(value);
  }
});

(async () => {
  console.log('A waiting');
  const value = await promise;
  console.log(`A finished, got ${value}`);
})();

(async () => {
  console.log('B waiting');
  const value = await promise;
  console.log(`B finished, got ${value}`);
})();

trigger('hello');
console.log('And *two* things are waiting on the single promise');

我已尝试使用async/await来复制此操作,但没有成功。
以下代码片段无法工作:

let trigger = async () => {
  console.log('trigger should be called *once*');
  return 'hello';
};

(async () => {
  console.log('A waiting');
  const value = await trigger; // <-- What do I need to put here?
  console.log(`A finished, got ${value}`);
})();

(async () => {
  console.log('B waiting');
  const value = await trigger; // <-- What do I need to put here?
  console.log(`B finished, got ${value}`);
})();

trigger(); // <-- How can this "kick off" the two awaits above?

使用async/await,能否编写与第一个片段相同的功能?

如果需要,我可以回退到使用Promise。

1个回答

5
要使用await,您需要引用单个promise,因此您不能按需调用函数并创建一个promise,然后在其他地方使用该promise(除非创建promise的函数还将其保存在状态中以返回给其他调用者,例如单例)。
我会最初创建一个单一的promise,然后将其发送到异步函数中:

const trigger = async () => {
  console.log('trigger should be called *once*');
  return 'hello';
};

async function as1(prom) {
  console.log('A waiting');
  const value = await prom;
  console.log(`A finished, got ${value}`);
}

async function as2(prom) {
  console.log('B waiting');
  const value = await prom;
  console.log(`B finished, got ${value}`);
}

const thePromise = trigger();
as1(thePromise);
as2(thePromise);

不要仅仅为了返回一个promise而使用async,如果一个函数的目的是创建一个promise,请明确地进行操作,这样可以更清晰地表达您的代码意图。Async和await并没有使Promise关键字过时,它只是在某些情况下有用的语法糖(在其他情况下则是不必要的)。

啊哈,这很有道理。我可以使用一个单一的工具来包装async function as1async function as2,该工具将Promise作为参数,并返回一个等待Promise的函数。这样所有重复的逻辑都在一个地方了。我想我会这么做。 - Joe Frambach

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接