Last active
December 6, 2016 15:05
-
-
Save ptdecker/733548b08d12161c2ed0 to your computer and use it in GitHub Desktop.
Node.js Serial Execution of an Array of Callback Functions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* Control Flow 4 - Serial Execution of an Array of Callback Functions | |
| * | |
| * Based on: | |
| * - http://book.mixu.net/node/ch7.html | |
| * - https://github.com/mixu | |
| * | |
| * Revised based upon comments from 'lanzz' to use 'process.nextTick(next)' instead of 'next()' | |
| * Revised based upon comments from 'Israel' to use "typeof(callback) != 'undefined'" | |
| * | |
| * The 'Array.prototype.slice.call(arguments)' usage is a JavaScript trick and explained here: | |
| * - http://mariapacana.tumblr.com/post/79170518832/javascript-tricks | |
| * - http://stackoverflow.com/questions/7056925/how-does-array-prototype-slice-call-work | |
| * | |
| * Characteristics: | |
| * - Flow control construct 'series' is recursive | |
| * - Runs a number of operations sequentially | |
| * - Only starts one async operation at a time (no concurrency) | |
| * - Ensures that the async function complete in order | |
| * | |
| * Variations: | |
| * - The way in which the result is collected (manual or via a “stashing” callback) | |
| * - How error handling is done (manually in each sub-function, or via a dedicated, additional function) | |
| * - Since execution is sequential, there is no need for a “final” callback | |
| * | |
| * Tags: sequential, no-concurrency, no-concurrency-control, array of functions work queue | |
| */ | |
| /* | |
| * A Simulated Asynchronous Function | |
| */ | |
| function async(arg, callback) { | |
| var delay = Math.floor(1000 * Math.random()); | |
| console.log('Do something with "' + arg + '", and return ' + delay + 'ms later'); | |
| setTimeout(function() { | |
| result = arg; // Keep results same as argument so impact of async can be viewed | |
| callback(result); | |
| }, delay); | |
| } | |
| /* | |
| * Simulated Completion Function | |
| */ | |
| function final(results) { | |
| console.log('Done', results); | |
| console.log(process.hrtime(start)[0] + "." + (process.hrtime(start)[1] / 1000000).toFixed(0) + " sec(s) total time"); | |
| } | |
| /* | |
| * Recursive 'Series' Flow Control Construct with Callback Functions Passed as a Work Queue | |
| */ | |
| function series(results, callbacks, last) { | |
| function next() { | |
| var callback = callbacks.shift(); | |
| if (typeof(callback) != 'undefined') { | |
| callback(function() { | |
| results.push(Array.prototype.slice.call(arguments)); | |
| console.log("Results so far: ", results); | |
| next(); | |
| }); | |
| } else { | |
| last(results); | |
| } | |
| } | |
| process.nextTick(next); | |
| } | |
| /* | |
| * Main | |
| */ | |
| var start = process.hrtime(); | |
| var results = []; | |
| series(results, [ | |
| function(next) { | |
| async(1, next); | |
| }, | |
| function(next) { | |
| async(2, next); | |
| }, | |
| function(next) { | |
| async(3, next); | |
| }, | |
| function(next) { | |
| async(4, next); | |
| }, | |
| function(next) { | |
| async(5, next); | |
| }, | |
| function(next) { | |
| async(6, next); | |
| }, | |
| function(next) { | |
| async(7, next); | |
| }, | |
| function(next) { | |
| async(8, next); | |
| }, | |
| ], final); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment