Выполнение функции обратного вызова после завершения .forEach - PullRequest
0 голосов
/ 20 мая 2018

Я пытаюсь выполнить функцию после того, как цикл forEach завершил все итерации.

Этот ответ предоставляет интересное решение, но я не могу заставить его работать.

Вот код, который я адаптировал, создав простую функцию asyncFunction ().

function callback () { console.log('all done'); }
function asyncFunction(item) {
  console.log("in async function, item is " + item)
}
var itemsProcessed = 0;

[1, 2, 3].forEach((item, index, array) => {
  asyncFunction(item, () => {
    itemsProcessed++;
    console.log("in callback area, itemsProcessed is " + itemsProcessed )
    if(itemsProcessed === array.length) {
      callback();
    }
  });
});

Как видно из этого JSfiddle , скрипт правильно выполняет асинхронную функцию, но не может ввести часть, которая увеличивает itemsProcessed и должна вызвать функцию callback().

Я не слишком знаком с функциями жирной стрелки, поэтому, возможно, ошибка связана с их использованием.

Кто-нибудь может объяснить, почему скрипт не работает должным образом?

Ответы [ 3 ]

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

Сопоставьте каждый элемент с Обещанием, затем используйте Promise.all().

Promise.all([1, 2, 3].map(async num => num));

Конечно, вы можете сделать что-то более сложное внутри асинхронной функции, если хотите.

Promise.all([1, 2, 3].map(num => 
{
    return new Promise((reject, resolve) =>
    {
        setTimeout(() => resolve(num), 5000);
    })
}));

И если код, который вы выполняете, является синхронным или требует времени ожидания, тогда используйте конструктор Promise вместо асинхронной функции.

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

Поскольку вы хотите передать функцию обратного вызова в качестве второго аргумента asyncFunction, вам необходимо указать, что в качестве второго аргумента будет использоваться функция обратного вызова, и вам необходимо вызывать ее следующим образом:

function asyncFunction(item, cb) {
  console.log("in async function, item is " + item)
  cb()
}

Кроме того, ваш код можно переписать, чтобы было проще понять использование функции обратного вызова.Ваш код:

[1, 2, 3].forEach((item, index, array) => {
  asyncFunction(item, () => {
    itemsProcessed++;
    console.log("in callback area, itemsProcessed is " + itemsProcessed )
    if(itemsProcessed === array.length) {
      callback();
    }
  });
});

совпадает с:

[1, 2, 3].forEach((item, index, array) => {
  function cbFunc() {
    itemsProcessed++;
    console.log("in callback area, itemsProcessed is " + itemsProcessed )
    if(itemsProcessed === array.length) {
      callback();
    }
  }
  asyncFunction(item, cbFunc);
});
0 голосов
/ 20 мая 2018

Это тот случай, когда более современный подход заключается в использовании обещаний

function asyncFunction(item) {
   // return a promise
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log("in async function, item is " + item)
      // resolve promise when data is ready
      resolve(item)
    }, Math.random()*2000)// random delay to stagger order of returns

  })

}

// create array of promises
let promiseArray = [1, 2, 3].map(asyncFunction);

// runs when all promises are resolved
Promise.all(promiseArray).then(results => {
  console.log('all done')
  // results array will be in same order as original array
  console.log('results are: ', results)
})
.as-console-wrapper {max-height: 100%!important;top:0}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...