如何正确同步解析typescript/javascript中的承诺列表

如何正确同步解析typescript/javascript中的承诺列表,javascript,typescript,es6-promise,Javascript,Typescript,Es6 Promise,我有从数据库中获取数据、修改和保存的承诺列表, 有些承诺可以与相同的数据一起工作,为了排除可能的冲突,我决定执行承诺同步,我编写下一个函数,但我怀疑它可以更简单地完成,并且符合规则 打字稿 async function syncPromises<T>(arr: (() => Promise<T>)[]) { const result : T[] = []; for(const fn of arr) { result.push(await fn())

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

打字稿

async function syncPromises<T>(arr: (() => Promise<T>)[]) {
  const result : T[] = [];

  for(const fn of arr) {
    result.push(await fn());
  }

  return result;
}
目前我使用类似的代码调用函数

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

我认为这可以更简单

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

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;
}

与其采用函数数组,不如采用值数组和单个函数来应用它们-基本上是
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;
}

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

本页很好地解释了选项和差异:

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


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

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

本页很好地解释了选项和差异:

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


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

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


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

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


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

承诺不会“执行”。您的
arr
中包含的是返回承诺的函数,您可以按顺序运行它们。你不能用一系列的承诺来实现这一点,你唯一能用承诺来实现的就是等待它。承诺不是“执行”的。您的
arr
中包含的是返回承诺的函数,您可以按顺序运行它们。你不能用承诺数组来做这件事,你唯一能用承诺来做的就是等待它Promise@HardCoreQual正确的。我仍然需要在类型声明中命名参数……在我的typescript版本中,需要使用(e:V)=>Promise而不是V=>Promise@HardCoreQual正确的。我仍然在努力解决类型声明中命名参数的要求…我想要等待第一个元素的解析承诺,开始下一个承诺,等待解析,开始下一个,你的代码开始所有的承诺。因为函数是一样的,所以我认为同时解析会更好。无论如何,根据您的用例,bergi的答案是正确的。我希望等待第一个元素的解决承诺,开始下一个承诺,等待解决,开始下一个,你的代码开始所有的承诺。因为函数是一样的,所以我认为同时解析会更好。无论如何,根据您的用例,bergi的答案是合适的。
const ids = [ 3, 5 ];
sequentialMap(ids, someLogicWhatNeedExecSync);
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);