├── .gitignore ├── component.json ├── bower.json ├── package.json ├── LICENSE ├── index.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Numerous always-ignore extensions 2 | *.diff 3 | *.err 4 | *.orig 5 | *.log 6 | *~ 7 | 8 | # OS or Editor folders 9 | .DS_Store 10 | .cache 11 | Icon? 12 | 13 | # Folders to ignore 14 | .hg 15 | .svn 16 | 17 | # Node.js package manager 18 | /node_modules 19 | /npm-debug.log 20 | 21 | # Other stuff 22 | *.pyc 23 | /tmp 24 | 25 | # Project stuff 26 | -------------------------------------------------------------------------------- /component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "async-waterfall", 3 | "repo": "es128/async-waterfall", 4 | "description": "Runs a list of async tasks, passing the results of each into the next one", 5 | "version": "0.1.5", 6 | "keywords": ["async", "waterfall", "tasks", "control", "flow"], 7 | "main": "index.js", 8 | "scripts": ["index.js"], 9 | "dependencies": {}, 10 | "development": {} 11 | } 12 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "async-waterfall", 3 | "repo": "es128/async-waterfall", 4 | "description": "Runs a list of async tasks, passing the results of each into the next one", 5 | "version": "0.1.5", 6 | "keywords": ["async", "waterfall", "tasks", "control", "flow"], 7 | "main": "index.js", 8 | "scripts": ["index.js"], 9 | "dependencies": {}, 10 | "development": {}, 11 | "ignore": [ 12 | "**/.*", 13 | "node_modules", 14 | "components" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "async-waterfall", 3 | "version": "0.1.5", 4 | "description": "Runs a list of async tasks, passing the results of each into the next one", 5 | "author": { 6 | "name": "Elan Shanker", 7 | "url": "http://github.com/es128" 8 | }, 9 | "homepage": "https://github.com/es128/async-waterfall", 10 | "repository": { 11 | "type": "git", 12 | "url": "git://github.com:es128/async-waterfall.git" 13 | }, 14 | "bugs": { 15 | "url": "https://github.com/es128/async-waterfall/issues" 16 | }, 17 | "main": "./index", 18 | "keywords": ["async", "waterfall", "tasks", "control", "flow"], 19 | "dependencies": {} 20 | } 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Elan Shanker 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the “Software”), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | // MIT license (by Elan Shanker). 2 | (function(globals) { 3 | 'use strict'; 4 | 5 | var nextTick = function (fn) { 6 | if (typeof setImmediate === 'function') { 7 | setImmediate(fn); 8 | } else if (typeof process !== 'undefined' && process.nextTick) { 9 | process.nextTick(fn); 10 | } else { 11 | setTimeout(fn, 0); 12 | } 13 | }; 14 | 15 | var makeIterator = function (tasks) { 16 | var makeCallback = function (index) { 17 | var fn = function () { 18 | if (tasks.length) { 19 | tasks[index].apply(null, arguments); 20 | } 21 | return fn.next(); 22 | }; 23 | fn.next = function () { 24 | return (index < tasks.length - 1) ? makeCallback(index + 1): null; 25 | }; 26 | return fn; 27 | }; 28 | return makeCallback(0); 29 | }; 30 | 31 | var _isArray = Array.isArray || function(maybeArray){ 32 | return Object.prototype.toString.call(maybeArray) === '[object Array]'; 33 | }; 34 | 35 | var waterfall = function (tasks, callback) { 36 | callback = callback || function () {}; 37 | if (!_isArray(tasks)) { 38 | var err = new Error('First argument to waterfall must be an array of functions'); 39 | return callback(err); 40 | } 41 | if (!tasks.length) { 42 | return callback(); 43 | } 44 | var wrapIterator = function (iterator) { 45 | return function (err) { 46 | if (err) { 47 | callback.apply(null, arguments); 48 | callback = function () {}; 49 | } else { 50 | var args = Array.prototype.slice.call(arguments, 1); 51 | var next = iterator.next(); 52 | if (next) { 53 | args.push(wrapIterator(next)); 54 | } else { 55 | args.push(callback); 56 | } 57 | nextTick(function () { 58 | iterator.apply(null, args); 59 | }); 60 | } 61 | }; 62 | }; 63 | wrapIterator(makeIterator(tasks))(); 64 | }; 65 | 66 | if (typeof define !== 'undefined' && define.amd) { 67 | define([], function () { 68 | return waterfall; 69 | }); // RequireJS 70 | } else if (typeof module !== 'undefined' && module.exports) { 71 | module.exports = waterfall; // CommonJS 72 | } else { 73 | globals.asyncWaterfall = waterfall; //