Code Monkey home page Code Monkey logo

async-waterfall's Introduction

async-waterfall

Simple, isolated async waterfall module for JavaScript.

Runs an array of functions in series, each passing their results to the next in the array. However, if any of the functions pass an error to the callback, the next function is not executed and the main callback is immediately called with the error.

For browsers and node.js.

Installation

  • Just include async-waterfall before your scripts.
  • npm install async-waterfall if you’re using node.js.
  • component install es128/async-waterfall if you’re using component(1).
  • bower install async-waterfall if you’re using Twitter Bower.

Usage

  • waterfall(tasks, optionalCallback);
  • tasks - An array of functions to run, each function is passed a callback(err, result1, result2, ...) it must call on completion. The first argument is an error (which can be null) and any further arguments will be passed as arguments in order to the next task.
  • optionalCallback - An optional callback to run once all the functions have completed. This will be passed the results of the last task's callback.
Node.js:
var waterfall = require('async-waterfall');
waterfall(tasks, callback);
Browser:
// component(1)
var waterfall = require('async-waterfall');
waterfall(tasks, callback);

// Default:
window.asyncWaterfall(tasks, callback);
Tasks as Array of Functions
waterfall([
  function(callback){
    callback(null, 'one', 'two');
  },
  function(arg1, arg2, callback){
    callback(null, 'three');
  },
  function(arg1, callback){
    // arg1 now equals 'three'
    callback(null, 'done');
  }
], function (err, result) {
  // result now equals 'done'
});
Derive Tasks from an Array.map
/* basic - no arguments */
waterfall(myArray.map(function (arrayItem) {
  return function (nextCallback) {
    // same execution for each item, call the next one when done
    doAsyncThingsWith(arrayItem, nextCallback);
}}));

/* with arguments, initializer function, and final callback */
waterfall([function initializer (firstMapFunction) {
    firstMapFunction(null, initialValue);
  }].concat(myArray.map(function (arrayItem) {
    return function (lastItemResult, nextCallback) {
      // same execution for each item in the array
      var itemResult = doThingsWith(arrayItem, lastItemResult);
      // results carried along from each to the next
      nextCallback(null, itemResult);
}})), function (err, finalResult) {
  // final callback
});

Acknowledgements

Hat tip to Caolan McMahon and Paul Miller, whose prior contributions this is based upon.

License

MIT

async-waterfall's People

Contributors

es128 avatar paulmillr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

async-waterfall's Issues

waterfall within waterfall

Having one inside the other causes last callback() in chain of the outer waterfall to be undefined:

var obj = {
a : {},
b : {}
}
var waterfall = require('async-waterfall');
waterfall(
[
function(callback){

    waterfall([
            function(callback1){
                var i = 'test';
                callback(null, i);
            },function(i, callback){
                callback(null, i);
            }
        ], function(err1, res1){
            console.log(res1);
    });

    obj.a = {this: 1, that: 2};
    callback(null);
}
, 
function(callback){
    obj.b = {bee: 3, tee: 4};
    callback(null, true); //<- this one is undefined
}

],
function(err, res){
if(err){
return ;
}
console.log('obj', obj);
});

Refactoring

Hi, I tried to re-implement this functionality with the following code. Please correct me if there is any mistake.

function waterfall(fns, cb) {
    if (Reflect.toString.call(fns) !== '[object Array]') {
        throw Error('waterfall第一个参数必须为数组')
    }
    if (typeof cb !== 'function') {
        throw Error('waterfall第二个参数必须为函数')
    }
    let [fnErr, fnArgs, isBreak] = [null, [], false]
    const fnCb = function (err, ...args) {
        fnErr = err
        fnArgs = args
    }
    for (const fn of fns) {
        if (fnErr !== null) {
            isBreak = true
            cb(fnErr)
            break
        }
        fn(...fnArgs, fnCb)
    }
    if (!isBreak) {
        cb(fnErr, ...fnArgs)
    }
}

Add callback error in example

I would like to see how one uses the error functionality in the callback. I have tried to run callback with first parameter being a true value but next functions still run. An example of how this works would be great as I'm just guessing the functionality now.

Does not work as expected with Component.js

With component.js, the module object used is actually a function, so typeof module yields "function", which bypasses the CommonJS check in the UMD. (and thus gets added to the global object)

Consider switching typeof module === "object" to typeof module !== "undefined".

"Derive Tasks from an Array.map" does not seem to work

Your basic example:
var waterfall = require('async-waterfall');

var myArray = [1,2,3];

waterfall(myArray.map(function (arrayItem) {
return function (lastItemResult, nextCallback) {
// same execution for each item in the array
var itemResult = arrayItem * lastItemResult;
// results carried along from each to the next
nextCallback(null, itemResult);
}}), function (err, result) {
// final callback
console.log(result);
});

Error:
nextCallback(null, itemResult);
^
TypeError: undefined is not a function

Example when using iterator and exit function

Running this snippet

var step=function(item,nextCallback) {
 console.log("next",item)
 nextCallback.apply(this,[item,nextCallback])
}
waterfall([...new Array(5).keys()].map(function (arrayItem) {
  return (nextCallback) => {
	step(arrayItem,nextCallback)    
  }
}));

I get only

next 0
next 1

or adding an exit function

waterfall([...new Array(5).keys()].map(function (arrayItem) {
  return (nextCallback) => {
	step(arrayItem,nextCallback)    
  }
}),(results)=> {
   console.log(results)
});

I get 1 as result that is correct, but it ends after two iterations.

What's wrong?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.