передача asyn c функций в обещание. все () - PullRequest
1 голос
/ 21 апреля 2020

Я знаю, promise.all() ожидает массив обещаний.

Но возможно ли сделать что-то подобное ниже? Если нет, пожалуйста, предложите обходной путь.

Не рекомендуется использовать await внутри for l oop. Вот почему я добавляю массив и делаю 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 ]

2 голосов
/ 21 апреля 2020

Первая проблема заключается в том, что Promise.all принимает массив обещаний , а не массив функций - ваш текущий код не будет работать.

Основная проблема заключается в том, что вы ' только условно с использованием результата асинхронной операции. Вы можете связать .then с Обещанием, чтобы Обещание разрешило результат .then, а не его первоначальное значение разрешения. То есть:

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

приводит к Promise, который разрешается до 6.

Используя эту логику c, вы можете pu sh Promise для массива, который в его then, условно работает с результатом (distances = response.data...) и возвращает окончательное значение, или ничего не возвращает. В конце вызовите Promise.all для массива Promises и отфильтруйте по логическому:

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
0 голосов
/ 21 апреля 2020

Вы должны pu sh Обещать объект в массив. так что просто оберните функцию asyn c с помощью Promise.

0 голосов
/ 21 апреля 2020

Функция в вашем примере никогда не выполняется, для их разрешения вы можете сделать следующее (обернуть ее в скобки и сразу вызвать):

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())
...