我正在转换同事的一些旧代码,我对Javascript并不陌生,但我生疏了,我是Promises,Map和其他新JS功能的新手。
我需要将带有await
的for
循环转换为可以在更大的 Promise 链中使用的Promise
。
我认为答案是Promise.all
和Map / 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)
}
);