K
K
kuzubina2019-11-04 12:03:12
JavaScript
kuzubina, 2019-11-04 12:03:12

Linear execution of functions via callback in Node.js?

Help to understand with linear execution of functions.
There is this code

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);

I'm trying to force functions to run sequentially through callbacks, but something doesn't work.
The getHistory() function takes an id from one object in a loop and, according to these id, the getDetailedHistory() and getDetailedHistoryReverse() functions make http requests, collect information and write to a new allHomeEvent array
How to make the test() function work after it is generated allHomeEvent array. Now it shows an empty array in the console, and if you run it through a settimeout, then it normally displays the generated array

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Anton Shvets, 2019-11-04
@Xuxicheta

This is what your response looks like on callbacks. Primitive version, without error handling. In fact, this is its own mini-implementation of 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!'));

Think about how to move the execution of all requests into a separate function for reuse in the future.
To be like this
const requests = getHistory(allHomeEvent);
doneAll(requests, () => console.log('all done!'));

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question