@kuzubina

Линейное выполнение функций через callback в Node.js?

Помогите разобраться с линейным выполнением функций.
Есть вот такой код
allHomeEvent = [];
function getHistory(callback) {
	for (let event of lastGame) {
		let itemId = event.id

		if (event.home.name === "Women") {
		getDetailedHistory(itemId, allHomeEvent)
	} 

	if (event.away.name === "Women") {
		getDetailedHistoryReverse(itemId, allHomeEvent)
	}
	}

	callback();
}

function test () {
	console.log(allHomeEvent)
}

getHistory(test);

Пытаюсь через колбэки заставить последовательно запускаться функции, но что-то не получается.
Функция getHistory() циклом берет id из одного объекта и по этим id функции getDetailedHistory() и getDetailedHistoryReverse() делают http запросы, собирают инфу и записывают в новый массив allHomeEvent
Как сделать так, чтобы функция test() срабатывала после того, как будет сформирован массив allHomeEvent. Сейчас она в консоль так и показывает пустой массив, а если запустить через сеттаймаут, тогда нормально выводит сформированный массив
  • Вопрос задан
  • 117 просмотров
Пригласить эксперта
Ответы на вопрос 1
Xuxicheta
@Xuxicheta
инженер
Вот так примерно выглядит ваш ответ на коллбэках. Примитивный вариант, без обработок ошибок. Фактически это своя миниреализация Promise.all

// имитация реквеста
function getDetailedHistory(itemId, allHomeEvent, done) {
  setTimeout(300, () => done('im getDetailedHistory'));
}

// имитация реквеста
function getDetailedHistoryReverse(itemId, allHomeEvent, done) {
  setTimeout(400, () => done('im getDetailedHistoryReverse'));
}


function getHistory(allHomeEvent, callback) {
  // вместо запуска сначала соберем все запросы в массив функций.
  const requests = [];
  for (const event of allHomeEvent) {
    let itemId = event.id

    if (event.home.name === "Women") {
      // записываем в массив функцию, замыкающую наш реквест
      requests.push(done => getDetailedHistory(itemId, allHomeEvent, done));
    }

    if (event.away.name === "Women") {
    	requests.push(done => getDetailedHistoryReverse(itemId, allHomeEvent, done));
    }
  }

  // запомнить число реквестов, чтобы понять когда все закончились, они же асинхронны.
  let counter = requests.length;
 
   // при окончании каждого реквеста, уменьшаем счетчик и смотрим уже конец или еще нет
   const requestDone = () => {
  	counter -= 1;
    if (counter <= 0) {
       // реквесты кончились, пора дергнуть главный коллбэк
    	callback();
    }
  }
  
  // а теперь пора выполнить весь массив
   requests.forEach(request => request(requestDone));
}

getHistory(allHomeEvent, () => console.log('all done!'));


Подумайте как вынести выполнялку всех запросов в отдельную функцию, для переиспользования в дальнейшем.
Чтобы было так
const requests = getHistory(allHomeEvent);
doneAll(requests, () => console.log('all done!'));
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы