如何将循环等待转换为承诺?



我正在转换同事的一些旧代码,我对Javascript并不陌生,但我生疏了,我是Promises,Map和其他新JS功能的新手。

我需要将带有awaitfor循环转换为可以在更大的 Promise 链中使用的Promise

我认为答案是Promise.allMap / Stream / Reduce(我仍在学习哪个是为了什么(,但我看过的所有媒体文章都解释得很差(我可能不知道搜索正确的东西(。

这是我正在转换的代码:

//foos and bars are global and can be used in the `then` after this promise resolves, 
//  so what the promise returns is unimportant
for (let bar of bars) {
foos[bar] = await new MyClass(bar).myAsyncOperation();
}

如何转换循环,以便在循环中的所有项目完成之前不会解析承诺?

另外,我应该转换myAsyncOperation以返回承诺还是可以/应该将其保留为异步函数?

只需从您的bars创建一个新的承诺数组,最好使用Array.map,然后将该数组传递给Promise.all得到他们的结果。

// Wrap main code in an async IIFE so we can use await.
(async () => {
let bars = [1,2,3,4]
// Sample async function which implicitly returns a Promise since it's marked
// as async. Could also be a regular function explicitly returning a Promise.
const myAsyncOperation = async bar => bar * 5
// Create an array of Promises from bars.
const tasks = bars.map(bar => myAsyncOperation(bar))
try {
// Pass the Promises to Promise.all and get results.
const results = await Promise.all(tasks)
console.log(results)
} catch (err) {
console.error(err)
}
})()

for..of示例的不同之处在于,Promise.all不会等待每个单独的 Promise 解决后再继续下一个 Promise。它或多或少是平行的,而不是连续的。

。另外,我应该转换myAsyncOperation以返回承诺或 我可以/应该将其保留为异步函数吗?

好吧,如果myAsyncOperation是一个async标记的函数,那么它已经返回了一个Promise。将函数标记为async会导致它始终隐式返回Promise

Promise.all

是要走的路:

Promise.all(bars
.map(foo => new MyClass(foo).myAsyncOperation()))
.then(results => {
console.log(results)
}
);

最新更新