如何正确地同步解析typescript/javascript中的promise列表



我有从数据库中获取数据、修改数据和保存数据的承诺列表,一些promise可以与相同的数据一起工作,以排除可能的冲突,我决定同步执行promise,我编写下一个函数,但我怀疑它可以更简单地完成,并且符合规则。

打字

async function syncPromises<T>(arr: (() => Promise<T>)[]) {
const result : T[] = [];
for(const fn of arr) {
result.push(await fn());
}
return result;
}

JavaScript

async function syncPromises(arr) {
const result = [];
for(const fn of arr) {
result.push(await fn());
}
return result;
}

目前我使用类似的代码调用功能

const ids = [ 3, 5 ];
syncPromises(ids.map(id => () => someLogicWhatNeedExecSync(id)));

我认为这可以是更简单的

不采用函数数组,而是采用值数组和单个函数来应用于它们-基本上是map:

async function sequentialMap<V, R>(arr: V[], fn: (v: V) => Promise<R>): Promise<R[]> {
const result : R[] = [];
for (const value of arr) {
result.push(await fn(value));
}
return result;
}

您可以将其用作

const ids = [ 3, 5 ];
sequentialMap(ids, someLogicWhatNeedExecSync);

JavaScript和TypeScript在循环您想要等待的函数时有一些微妙之处。

本页很好地解释了选项和差异:https://advancedweb.hu/how-to-use-async-functions-with-array-foreach-in-javascript/

如果您希望在返回之前解决所有承诺,那么您不能使用for循环,而应该使用arr.map()arr.reduce()

在您想要返回数组的情况下,最简单的方法可能是在返回数组时使用arr.map()

绝对同意@Bergi提到的方法。另一种方法是使用Promise.all()

function asyncTimeoutFunction(id){
return new Promise(resolve=>{
setTimeout(()=>resolve(id),1000);
})
}
const ids = [ 3, 5, 2 ];
const functions = ids.map((id)=>{
return asyncTimeoutFunction(id);
});
Promise.all(functions).then(console.log);

只需将异步函数替换为asyncTimeoutFunction。

最新更新