tony
tony

Reputation: 315

Node JS Sync Work flow with Async request

Currently try to learn Node JS and getting my head around Async/Sync workflow.

Try to the follow:

Step 1: - Get data 1 with function 1 - Get data 2 with function 2 - Get data 3 with function 3

Step2: - Work out logic with data 1,2,3

Step 3 - Do final call


I been looking at Q and Async packages but still havent really find an example.

Can some one show me how they will go about this issue in Node JS?

Thanks

Upvotes: 1

Views: 382

Answers (4)

joemillervi
joemillervi

Reputation: 1067

Probably the best thing to do is use Promises like @Tyler here states. However, for conceptual understanding it is best to first understand the node callback pattern.

Because some tasks take time, we give the task a function and say 'When you are done, put the data you retrieved into this function'. These functions that we give to other functions are called callbacks. They must be constructed to accept the data, and also an error in case there is a problem while fetching the data. In Node the error is the first callback parameter and the data is the second.

fs.readFile('/file/to/read.txt', function callback(error, data) {        
  if (error) console.log(error);  
  else console.log(data);
});

In this example, once node reads the file, it will feed that data into the callback function. In the callback we must account for the case that there was a problem and handle the error.

In your question you want to do multiple async tasks and use their results. Therefore you must take this pattern and nest several of them. So, continuing this example, if there is no error you will begin another async task.

fs.readFile('/file/to/read.txt', function callback(error, data) {        
  if (error) console.log(error);  
  else {
    someOtherAsyncThing(function callback(error, data2) {
      if (error) console.log(error);
      else {
        console.log(data + data2)
      }
    });
  }
});

Upvotes: 0

Tyler
Tyler

Reputation: 18157

You can setup a chain of Promises to do things sequentially:

var funcA = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('some data from A')
        }, 1000)
    });
}

var funcB = (dataFromA) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(dataFromA + ' data from B')
        }, 2000)
    })
}

var funcC = (dataFromB) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(dataFromB + ' data from C')
        }, 500)
    })
}

// Doing the functions on after another
funcA().then(funcB).then(funcC).then((data) => {
    console.log(data);
})

Or if you want to do them all at the same time you can use Promise.all():

var promises = [];

promises.push(new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('some data from A')
    }, 1000)
}));

promises.push(new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('some data from B')
    }, 1000)
}));

promises.push(new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('some data from C')
    }, 1000)
}));

// Execute the array of promises at the same time, and wait for them all to complete
Promise.all(promises).then((data) => {
    console.log(data);
})

Upvotes: 0

Dom O'Connell
Dom O'Connell

Reputation: 26

Not entirely clear on your implementation, but depending on how specific your ordering needs to be you could try something like this:

var data1 = null;
var data2 = null;
var data3 = null;

async.series([
    function(httpDoneCallback){
        async.parallel([
            function(data1Callback){
                $http(...).then(function(response){
                    // some logic here
                    data1 = response;
                    data1Callback();
                })
            },
            function(data2Callback){
                $http(...).then(function(response){
                    // some logic here
                    data2 = response;
                    data2Callback();
                })
            },
            function(data3Callback){
                $http(...).then(function(response){
                    // some logic here
                    data3 = response;
                    data3Callback();
                })
            }
        ], function(){
            //all requests dome, move onto logic
            httpDoneCallback();
        })
    },
    function(logicDoneCallback){
        // do some logic, maybe more asynchronous calls with the newly acquired data
        logicDoneCallback();
    }
], function(){
    console.log('all done');
})

Upvotes: 1

jaxoncreed
jaxoncreed

Reputation: 1128

Do you want function 1, 2, and 3 to trigger at the same time? If so then this should help:

var async = require('async');
async.parallel([
    function(cb1) {
        cb1(null, "one")
    },
    function(cb2){
        cb2(null, "two")
    },
    function(cb3){
        cb3(null, "three")
    }
], function(err, results) {
    console.log(results); // Logs ["one", "two", "three"]
    finalCall();
});

To explain, every function in the array submitted as the first param to the parallel method will also receive a callback function. Activating the callback function signifies that you're done fetching your data or doing whatever you need to do in said function. All three functions will trigger at the same time, and once all three callbacks are called, the final function is called. The callback accepts two parameters: "error", and "result." If everything's successful, pass "null" as the error parameter. The results will be given to the final function as an array containing each of the results for your individual functions.

Upvotes: 0

Related Questions