将异步函数传递给promise.all()

时间:2020-04-21 06:54:59

标签: javascript promise async-await

我知道promise.all()期望有一系列的承诺。

但是,有可能做下面的事情吗?如果否,请提出解决方法。

不建议在await循环内使用for。这就是为什么我要推入数组并对此进行promise.all()的原因。

var functionArray = [];
for (let i = 0; i < jobs.length; i += 1) {
  ...
  if (params.origins !== '' && params.destinations !== '') {
    functionArray.push(async function() {
      response = await getDistance(params.origins, params.destinations);
      if (response.error) {
        // handle error
        return null
      } else {
        distances = response.data.rows[0].elements.map((el, index) => {
          el.emp_id = empIdOrder[index];
          return el;
        });
        sortedDistances = sortDistance(distances);
        return formatDataForInsert(jobs[i].job_id, sortedDistances);
      }
    });
  }
}
var dataToBeinserted = await Promise.all(functionArray); // return an array with results

它没有按预期工作。

await Promise.all(functionArray);始终返回[ [AsyncFunction], [AsyncFunction] ]

应该解决吗?

3 个答案:

答案 0 :(得分:3)

第一个问题是Promise.all接受一个 promises 数组,而不是一个函数数组-您当前的代码不起作用。

主要问题是,您只是有条件地使用异步操作的结果。您可以将.then链接到Promise,以使Promise解析为.then的结果,而不是其初始解析值。那是:

Promise.resolve(2)
  .then(res => res + 4)

产生一个承诺,结果为6。

使用此逻辑,您可以将Promise推送到数组,该数组在其then中有条件地与结果(distances = response.data...)一起使用,并返回最终值不返回任何内容。最后,在Promises数组上调用Promise.all,然后按布尔值进行过滤:

const promises = [];
for (let i = 0; i < jobs.length; i += 1) {
  if (params.origins !== '' && params.destinations !== '') {
    promises.push(
      getDistance(params.origins, params.destinations)
        .then((response) => {
          if (response.error) {
            // handle error
            return null
          } else {
            const distances = response.data.rows[0].elements.map((el, index) => {
              el.emp_id = empIdOrder[index];
              return el;
            });
            const sortedDistances = sortDistance(distances);
            return formatDataForInsert(jobs[i].job_id, sortedDistances);
          }
      })
    );
    }
}
const results = await Promise.all(promises)
  .filter(Boolean); // filter out failures

var dataToBeinserted = await Promise.all(functionArray); // return an array with results

答案 1 :(得分:0)

您的示例中的函数从未执行过,为了让他们解析,您可以这样做(将其括在括号中并立即调用):

functionArray.push((async function() {
  response = await getDistance(params.origins, params.destinations);
  if (response.error) {
    // handle error
    return null
  } else {
    distances = response.data.rows[0].elements.map((el, index) => {
      el.emp_id = empIdOrder[index];
      return el;
    });
    sortedDistances = sortDistance(distances);
    return formatDataForInsert(jobs[i].job_id, sortedDistances);
  }
})());

或者:

Promise.all(fnArray.map(f => f())

答案 2 :(得分:0)

您应将Promise对象推入数组。 因此,只需将Promise与异步功能包装在一起即可。