-1

Using NodeJS, I'm trying to get info from the database on a list of IDs and populate an array of objects. I need this to process synchronously. I'm having trouble figuring out how to do this so the next function call will wait for the previous one to finish before being called. Then all of the 'each' iterations to finish for the return to be called.

Example:

getInfo();

function getInfo(){
   var return_arr = Array();
   var ids = getListOfIDs();
   // loop through each id getting more info from db
   $.each( ids, function( i, v ){
       return_arr.push(getFullInfo( id ));
   });
   return return_arr;
}

function getListOfIDs(){
  // database call to get IDs
  // returns array
}

function getFullInfo(){
  // database call to get full info
  // returns object
}

This is a simplified example, so assume that a single query to get all info will not work as there are multiple joins going on and post processing that needs to take place in js. Also, assume I'm doing proper error handling, which I omitted in my example.

Kevin B
  • 94,570
  • 16
  • 163
  • 180
user6041966
  • 195
  • 12

3 Answers3

0

Your database queries are asynchronous so you need to either use callbacks or promises to perform your work once the database returns with results.

function getListOfIDs(callback) {
  // database call to get IDs
  db.query('...', function(data) {
    // call the callback and pass it the array
    callback(data);
  });
}

function getInfo() {
  // pass an anonymous function as a callback
  getListofIDs(function(data) {
    // we now have access to the data passed into the callback
    console.log(data);
  });
}
Soviut
  • 88,194
  • 49
  • 192
  • 260
  • Callbacks won't ensure that the calls are processed synchronously. Can you provide a code example with promises? – user6041966 Sep 19 '17 at 18:55
  • Callbacks ensures calls to be processed synchronously from my understanding. You just have to call the previous ones with later ones. – zhangjinzhou Sep 19 '17 at 19:16
  • Of course promise code is cleaner without the multiple levels embed. But callback should have not problem solving synchronous issue. – zhangjinzhou Sep 19 '17 at 19:17
  • @user6041966 Callbacks and promises work the same way; Both are async. Both wait for a long running operation to finish before calling a handler function. Both are guarenteed to fire when that operation completes. Neither is synchronous, nor is your database querying code. – Soviut Sep 20 '17 at 00:18
-1

Your current code example is synchronous, although I don't know how your db code works. The each loop is synchronous it just iterates over your ids and calls the getFullInfo function.

I'm not sure why you want synchronous code though as it doesn't utilise Nodes event loop architecture.

What I would do is use a good Promises framework such as Bluebird (http://bluebirdjs.com/docs/api/promise.each.html) with Promise.each ensuring each iteration occurs serially. Or you could also use a Callback library such as async (http://caolan.github.io/async/) with async.eachSeries. Either of these will ensure that you (a) get the benefit of asynchronous and (b) iterate in a serial fashion.

Click Ahead
  • 2,782
  • 6
  • 35
  • 60
-2

Promise way to do it:

function getListOfIDs() {
  return new Promise((resolve, reject) => {
       // database call
       if (err) 
       {
           reject(your_db_err);
           return;
       }
       resolve(your_db_result);
  });
}

function getInfo() {
    getListOfIDs().then((result) => {
        //do whatever you want with result
    })
    .catch((err) => {
        //handle your err
    });
}
zhangjinzhou
  • 2,461
  • 5
  • 21
  • 46