Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js consecutive method calls with nested callback formatting

Tags:

node.js

So I'm new to Node.js and Im just wondering if the way I have my code setup makes sense. Im coming from a Java background so the nested callback structure is new. I have a Node program that runs a bunch of code that I broke down into different methods. The thing is that the methods need to be called in order. My code has this structure right now:

functionOne(data, callback(err) {

   functionTwo(data, callback(err) {

      functionThree(data, callback(err) {

          functionFour(data, callback(err) {
             //Code
          });

      });

   });

});

This is very minimalistic, but is this structure ok? With Java, I'd take the return values of all the methods, then just pass them to the next function. From my understanding so far, the Java approach I just mentioned is one of the main things that Node.js was trying to eliminate. But anyway... Does that structure look ok, and is that how its intended to look? Just want to be sure that I'm not making any major errors with Node in general. Thanks!

like image 550
raisedandglazed Avatar asked Sep 13 '26 03:09

raisedandglazed


2 Answers

Your code structure looks fine if you work with callback pattern. But if you're interested in make your code cleaner and readable you would like to use Promises in your asynchronous function, so instead of pass a callback to your functions you could do something like this :

function asyncFunction (data){
   return new Promise(function(resolve, reject){
       // Do something with data
       // Here you can call reject(error) to throw an error
       resolve();
   });
}

And instead of nested function callbacks you can call then method of Promise.

asyncFunction(data)
.then(function(){
    // Promise resolved
    // Something has been done with data
});

With Promises you can also execute async fuctions in parallel :

Promise.all([asyncFunctionA(data), asyncFunctionB(data), asyncFunctionC(data)])
.then(function(){...});

EDIT

If you need to pass values of one function to another, your code should look like this :

asyncFunctionA(data)
.then(function(dataA){
    return asyncFunctionB(dataA);
})
.then(function(dataB){
    return asyncFunctionC(dataB);
})
.then(function(dataC){
// ...
});
like image 148
Jose Hermosilla Rodrigo Avatar answered Sep 16 '26 04:09

Jose Hermosilla Rodrigo


You should try to use promises to avoid your callback hell, so it could be something like these...

const Q = require('q'); // you can do a research for this module.
var myModule = {};
myModule.functionOne = (params) => {
  const deferred = Q.defer(); // wait for this to complete
  // body function
  deferred.resolve(data); // this would be the result of this function
  return deferred.promise; // data is the output on your function
}

myModule.functionTwo = (params) => {
  const deferred = Q.defer(); // wait for this to complete
  // body function
  deferred.resolve(data); // this would be the result of this function
  return deferred.promise; // data is the output on your function
}

myModule.doAll = (params) => {
   myModule.functionOne(params)
   .then((outputFunctionOne) => {
      // this is called after functionOne ends
      return myModule.functionTwo(outputFunctionOne);
   })
   .then((outputFunctionTwo) => {
      // this is called after function 2 ends
      if (outputFunctionTwo.success) {
        // if everything ok, resolve the promise with the final output
        deferred.resolve(outputFunctionTwo);
      } else {
        // reject the promise with an error message
        deferred.reject('error');
      }
   })
   .fail((err) => { 
      // this is call if the promise is rejected or an exception is thrown
      console.log(err); // TODO: Error handling
   })
   .done();
}

module.exports = myModule;

You can Chain as many promises as you want really easily, that way you get rid of the callback hell. Best part, you can do promises on Javascript or Node.js

Reference Link https://github.com/kriskowal/q

Hope this helps

like image 38
David Espino Avatar answered Sep 16 '26 02:09

David Espino



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!