Skip to content
shimondoodkin edited this page Jun 6, 2011 · 114 revisions

#Node-inflow

Node-inflow is a utility module which provides essential async control-flow functions for working with asynchronous JavaScript.

The new idea here is to use a shared object for called functions. The debugging made easy. Also I tried to use known function names for the known functionalities.

It is designed with user in mind and with experience.

How to install

Simply download it: git clone https://github.com/shimondoodkin/node-inflow.git

Methods:

step([shared], steps [,interval] [,debug])

example:

step({req:req,res:res}, steps [,interval] [,debug])

Alias: flow, step, Step, seq, serial

Sequential async execution of functions.

  • Description of arguments:

    • shared - It is an object that is shared between all function as this.shared, It is optional
    • steps - It is an array of functions to call one after another. see argfunc
    • callback - A function to call after all functions in steps are finished (each called this.next()) . It is argfunc. It is optional. *Is not developed yet
    • interval - It is a number, repeat the sequence after this setTimeout() It is optional. * It is not developed yet
    • debug - A boolean to show traces of calls to this.next() function in console.log, It is optional.
  • Examples:

       var inflow = require('node-inflow');

example1:

       inflow.step([
         function(){console.log("1");this.next();},
         function(){console.log("2");this.next();}
       ]);

example2:

       var shared={req:req,res:res};
       inflow.step(
        shared,
        [
         function(){this.shared.myvar=1;this.next();}
         ,
         function()
         {
          var shared=this.shared;
          var res=shared.res;
          res.writeHeaders([{'content-type':'text/html;charset=utf-8'}]);
          res.end(shared.myvar);
          this.next();
         }
       ]);

example3:

       inflow.step([
         function(){console.log("1");this.next();},
         function(){console.log("2");this.next();}
       ],true); // last argument is to print debug info in the console

parallel([shared],steps [,chunksize] [,callback] [,debug])

Parallel async execution of functions.

  • Description of arguments:

    • shared - It is an object that is shared between all function as this.shared, it is optional

    • steps - It is an array of functions to call in parallel. see argfunc

    • chunksize - It is a number, it limits the maximum amount of functions executed in one time. It is optional. * It is not developed yet

    • callback - A function to call after all functions in steps are finished (each called this.next()). It is argfunc

    • debug - A boolean to show traces of calls to this.next() function in console.log, It is optional.

      inflow.parallel(shared,
      [
       function(){  console.log("wait 1000"); setTimeout(this.next,1000); },
       function(){  console.log("wait 1500"); setTimeout(this.next,1500); }
      ] ,
      function(){  console.log("both function waited during the same period of time"); }
      );
      
  • More about: parallel

each([shared,]items,each_function [,callback] [,debug])

Aliases: map, reduce, forEach, foreach

It is an Async forEach implementation. It calls the each_function once for each item in items.

  • Description of arguments:
    • shared - It is an object that is shared between all function as this.shared, It is optional
    • items - It is an array or object of items to iterate through
    • each_function - function(value,key,items){ codehere; this.next();} A function to be executed for each item. It is argfunc, however the argfunc is usually not required and generally not intended to be used here.
    • callback - A function to call when done doing for-each. It is argfunc
    • debug - A boolean to show traces of calls to this.next() function in console.log, It is optional.

example:

    var items=[
               {phone:'111111111234',name:'Simon'},
               {phone:'222222221234',name:'Avi'}
              ];
              
    inflow.each(items,function (val){
     console.log(val.phone+" - "+val.name+"\r\n");
     this.next();
    },
    function (){
     console.log('done');
    });

output:

     111111111234 - Simon
     222222221234 - Avi
     done

while(shared, loop_function [,callback] [,debug])

  • Description of arguments:
    • shared - It is an object that is shared between all function as this.shared, It is optional
    • loop_function - function(){ codehere; this.next();} A function to be executed for each item. It is argfunc
    • callback - A function to call when done doing while. It is argfunc
    • debug - A boolean to show traces of calls to this.next() function in console.log, It is optional.

In while you have:

    this.break()=call_the_Callback,
    this.continue()=this.next();

Example:

    inflow.while({},function(){
     // code here
     if(!( while_condition )) return this.break();
     this.next();
    },
    function(){
     console.log('// after while code here');
    });

if(condition,iftrue,iffalse)

The if function is a conditional function call function. If the condition function is used then call in the condition function this.next(true/false); The iftrue function or iffalse function is executed with the same shared object as the if function was called.

  • Description of arguments:
    • condition - A boolean or a an async function.
    • iftrue - A function to call if the result is true. It is argfunc
    • iffalse - A function to call if the result is false. It is argfunc
         inflow.step(shared,
         [
          function(){  console.log("wait 1000"); setTimeout(this.next,1000); },
          inflow.if(
              function(){ this.next(Math.random()>0.5); },
              function(){  console.log("wait 1000"); setTimeout(this.next,1000); }
              ,
              function(){  console.log("wait 1500"); setTimeout(this.next,1500); }
          )
         ] ,
         function(){  console.log("random choice of period of time with async if"); }
         ) ;

Recursion

To do async recursion you do not need async control flow library it is already async ready. But you have to hold state, You do it by adding a shared object at the end of arguments. When calling the recursive function it is easy to copy the the name of the function and the arguments as is from function definition line to the place of calling the callback.

    function print_file_contents_n_times(filename_arg1,times_to_read,callback,shared)
    {
     if(!shared)shared={i:times_to_read};
     if(shared.i>0)
     {
      fs.readFile(filename, "binary", function(err, file) {  
         shared.i--;
         print_file_contents_n_times(filename_arg1,times_to_read,shared);
      }
     }
     else
     {
      callback();
     }
    }

Short examples for all functions:

    var inflow = require('node-inflow'); // require it
    shared_object={req:req,res:res};
    inflow.step(shared_object,[myfunction1,myfunction2,[myfunction3,[myfunction3_arg1,myfunction3_arg2]])
    inflow.parallel(shared_object,[myfunction1,myfunction2,[myfunction3,[myfunction3_arg1,myfunction3_arg2]],done_function);
    inflow.each(shared_object,array_or_object,foreach_function(value,key,array),done_function);
    inflow.while(shared,loop_function,done_function)

More info:

More examples:

Notes: