我可以使用 async/await 来等待 JavaScript 中的多个事件吗?
Posted
技术标签:
【中文标题】我可以使用 async/await 来等待 JavaScript 中的多个事件吗?【英文标题】:Can I use async/await to wait for multiple events in JavaScript? 【发布时间】:2017-09-30 12:33:21 【问题描述】:考虑以下情况:
const waitForEvent = async (api) =>
api.on('eventOne', () =>
return 'eventOne';
)
api.on('eventTwo', () =>
return 'eventTwo';
)
api.on('eventThree', () =>
return 'eventThree';
)
api.load();
我要做的是在异步函数内的api
变量上设置事件回调,触发api.load()
函数,然后返回首先发生的事件,在这种情况下是eventOne|eventTwo|eventThree
问题是,这个语法不好,这个例子不起作用。我找不到任何方法来使用 async/await 来实现这一点,不得不恢复到这样的承诺:
const waitForEvent = (api) =>
return new Promise(resolve) =>
api.on('eventOne', () =>
resolve('eventOne');
)
api.on('eventTwo', () =>
resolve('eventTwo');
)
api.on('eventThree', () =>
resolve('eventThree');
)
api.load();
所以我的问题是,这可以使用 async/await 来完成吗?无论如何,这可以使用新的 async/await es7 语法来完成吗?
【问题讨论】:
一个问题是您的return
语句从它们的特定事件处理函数返回它们的值,而不是主要的waitForEvent
函数
当然,我知道 :) 感谢您指出这一点。我正在想办法解决这个问题。
我不明白你所说的“我不得不恢复承诺”是什么意思。 async
/await
仍然使用承诺?而如果api
没有被promisified,则需要使用Promise
构造函数。
eventOne、eventTwo、eventThree是什么意思?是“其中一个”还是“任意数量的任意顺序”或“所有 3 个随机顺序”?我问是因为也许 Promise 不是解决您的问题的最佳抽象。
【参考方案1】:
由于async/await
允许我们以同步的方式(词法自上而下)编写异步构造,因此实际上并没有一种特定的方法可以同时执行 3 行不同的代码(或更准确地说,语句)。
最理想的 api 是 Promise.race
。
首先你将你的 api 回调转换为返回一个承诺:
const apiPromiseBuilder = (api) => (eventName) => new Promise(resolve => api.on(eventName, () =>
resolve(eventName);
));
然后你参加你需要的所有赛事:
const waitForEvent = (api) =>
const apiPromise = apiPromiseBuilder(api);
const promiseRace = Promise.race([
apiPromise('eventOne'),
apiPromise('eventTwo'),
apiPromise('eventThree')
]);
api.load();
return promiseRace;
;
或者使用async/await
:
async function waitForEvent(api)
const apiPromise = apiPromiseBuilder(api);
const promiseRace = Promise.race([
apiPromise('eventOne'),
apiPromise('eventTwo'),
apiPromise('eventThree')
]);
api.load();
const firstResult = await promiseRace;
return firstResult;
;
【讨论】:
那是我的直觉,也是我害怕的。以为我会在***上问一下。我对 async/await 持观望态度,如果在某些情况下必须将它与 Promise 混合使用,我不确定一直使用 Promise 并暂时放弃 async/await 是否更好。感谢您的详尽回答。 async/await 是基于 promise 的,只是隐藏了一些东西。你总是使用 Promise,尽管不是每次都明确表示。话虽如此,每种情况都是独一无二的,做你喜欢做的更好:) 似乎它不仅在幕后隐藏了东西,而且还施加了限制,例如仅返回一个变量,并且......好吧..我的帖子所涉及的整个限制。感谢您的反馈!以上是关于我可以使用 async/await 来等待 JavaScript 中的多个事件吗?的主要内容,如果未能解决你的问题,请参考以下文章
async/await 函数不等待。多个功能不按顺序运行和完成
等待 async/await 结果返回,以便使用这些值呈现动态 html