Как дождаться выполнения обещаний в цикле for перед возвратом значения - PullRequest
0 голосов
/ 24 мая 2018

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

Мой код выглядит так:

var str_list = [some strings];

let myFunction = () => {
    var array = [];
    for (i = 0; i < length; i++) {
        new Promise((resolve, reject) => {
            if (str_list[i] fulfills some conditions) {
                resolve();
            } else {
                reject(
                    throw new Error())
            }
        }).then(() => {
            array.push(i);
        }).catch((err) => {
            console.log(i, err);
        });
    }
    return array;
}

Есть ли хороший способ дождаться завершения цикла for, прежде чем возвращать значение

1 Ответ

0 голосов
/ 24 мая 2018

var str_list = ["..."];

let myFunction = async () =>
{
    const promises = [];
    for (i = 0; i < length; i++)
    {
        promises.push(new Promise((resolve, reject) =>
        {
            const condition = // ...
            resolve(condition ? str_list[i] : false);
        }));
    }

    return (await Promise.all(promises)).filter(f => f !== false);
}

Попробуйте это.По сути, он добавляет все обещания в массив, а затем вызывает для них Promise.all, который выполняет их параллельно и ожидает завершения всех.

Затем результатывозвращаются по порядку, те результаты, которые были переданы в функцию resolve() в каждом Promise, и будут str_list[i] или false.Затем вызов filter() удаляет все записи, которые false.

Если вы хотите быть краткими, то это может быть значительно упрощено:

var str_list = ["..."];

let myFunction = async () =>
{
    const promises = str_list.map(async (value, index) => condition ? value : false);

    return (await Promise.all(promises)).filter(f => f !== false);
}

Этот код работает так же, как и первый фрагмент кода;это просто намного короче.

Я сделал метод async, потому что нет способа вернуть результаты Promise без await его использования.Если вы не хотите использовать метод async, вы можете либо вернуть Promise, который затем можно подождать с помощью await или .then():

var str_list = ["..."];

let myFunction = () => {
  const promises = [];
  for (i = 0; i < length; i++) {
    promises.push(new Promise((resolve, reject) => {
      const condition = // ...
        resolve(condition ? str_list[i] : false);
    }));
  }

  return Promise.all(promises).then(strs => strs.filter(f => f !== false));
}

// myFunction().then(results => ...)

Или вы можете использовать обратный вызов:

var str_list = ["..."];

let myFunction = (callback) =>
{
    const promises = [];
    for (i = 0; i < length; i++)
    {
        promises.push(new Promise((resolve, reject) =>
        {
            const condition = // ...
            resolve(condition ? str_list[i] : false);
        }));
    }

    return Promise.all(promises).then(results => callback(results.filter(f => f !== false));
}

// myFunction(results => ...);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...