如何正确同步解决打字稿/javascript中的承诺列表

时间:2021-06-05 20:38:10

标签: javascript typescript es6-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)));

我认为这可以更简单

3 个答案:

答案 0 :(得分:2)

不是采用一组函数,而是采用一组值和一个应用于它们的函数 - 基本上是 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);

答案 1 :(得分:0)

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

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

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

如果您想返回一个数组,最简单的方法可能是使用 arr.map(),因为它返回一个数组。

答案 2 :(得分:0)

完全同意@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。