Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node async parallel inside waterfall

I'm building a server in Nodejs to retrieve data from some database. I've worked with the async library for some time now and figured out some things like putting a waterfall inside a parallel function.

I stumbled upon a problem where I first need to execute a query and then use that query's result in other queries that can be executed concurrently. The code looks something like this:

async.waterfall([
    function(callback) {
        connection.query(   query,
                            function(err, rows, fields) {
                                if (!err) {
                                    callback(null,rows);
                                } else {
                                    callback(null,"SORRY");
                                }
                            }
        );
    },
    async.parallel([
        function(resultFromWaterfall,callback) {
            connection.query(query,
                            function(err, rows, fields) {
                                if (!err) {
                                    callback(null,rows);
                                } else {
                                    callback(null,"SORRY");
                                }
                            }
           );
        },
        function(resultFromWaterfall,callback) {
            connection.query(query,
                            function(err, rows, fields) {
                                if (!err) {
                                    callback(null,rows);
                                } else {
                                    callback(null,"SORRY");
                                }
                            }
           );
        }
    ])
], finalCallback
);

Now my problem is to access the result from the waterfall function and to use it in the parallel functions.

like image 297
Hans Avatar asked Aug 31 '16 08:08

Hans


People also ask

Can async be parallel?

Asynchronous operations in parallelThe method async. parallel() is used to run multiple asynchronous operations in parallel. The first argument to async. parallel() is a collection of the asynchronous functions to run (an array, object or other iterable).

What is the difference between async waterfall and async series?

waterfall allows each function to pass on its results to the next function, while async. series passes all the task's results to the final callback. The async. waterfall() will pass only the result of the last function called to the main callback.

How do you use async await in async waterfall?

If you use the async keyword before a function definition, you can then use await within the function. When you await a promise, the function is paused in a non-blocking way until the promise settles. If the promise fulfills, you get the value back.


2 Answers

async.waterfall([
    function(callback) {
        connection.query(query,
            function(err, rows, fields) {
                if (!err) {
                    callback(null, rows);
                } else {
                    callback(null, "SORRY");
                }
            }
        );
    },
    function(prevData,callback){
      console.log(prevData);//Use it whereever you want.
      async.parallel([
          function(callbackOfAsyncParallel) {
              connection.query(query1,
                  function(err, rows1, fields1) {
                      if (!err) {
                          callbackOfAsyncParallel(null, rows1);
                      } else {
                          callbackOfAsyncParallel(null, "SORRY1");
                      }
                  }
              );
          },
          function(callback) {
              connection.query(query2,
                  function(err, rows2, fields2) {
                    if (!err) {
                        callbackOfAsyncParallel(null, rows2);
                    } else {
                        callbackOfAsyncParallel(null, "SORRY2");
                    }
                  }
              );
          }
      ],function mainCBOfParallel(err,reuslts){
        if(!err){
          //this will be done after tasks in async.parallel are finished.
          callback(null,results);
          //results[0]===>rows1
          //results[1]===>rows2
        }
      });
    }
], finalCallback);

You have two mistakes in your code,

  1. tasks should be a function to execute.
  2. async.parallel has only callbacks in its task functions.

Update

There are callbacks (callbackOfAsyncParallel) which will be called when a task in async.parallel is finished.

It should not invoke callback (callback) of async.waterfall.If done probably there may be error/unexpected results.

like image 129
vkstack Avatar answered Sep 22 '22 12:09

vkstack


Try this..

    async.waterfall([

  function(callback) {
    connection.query(query,
      function(err, rows, fields) {
        if (!err) {
          callback(null, rows);
        } else {
          callback(null, "SORRY");
        }
      }
    );
  },
  function(resultFromWaterfall, callback) {
    async.parallel([

      function() {
        connection.query(query,
          function(err, rows, fields) {
            if (!err) {
              callback(null, rows);
            } else {
              callback(null, "SORRY");
            }
          }
        );
      },
      function() {
        connection.query(query,
          function(err, rows, fields) {
            if (!err) {
              callback(null, rows);
            } else {
              callback(null, "SORRY");
            }
          }
        );
      }
    ]);
  }

], finalCallback);
like image 25
abdulbarik Avatar answered Sep 22 '22 12:09

abdulbarik