# JavaScript Sync/Async forEach An optionally-asynchronous forEach with an interesting interface. ## Getting Started This code should work just fine in Node.js: First, install the module with: `npm install async-foreach` ```javascript var forEach = require('async-foreach').forEach; forEach(["a", "b", "c"], function(item, index, arr) { console.log("each", item, index, arr); }); // logs: // each a 0 ["a", "b", "c"] // each b 1 ["a", "b", "c"] // each c 2 ["a", "b", "c"] ``` Or in the browser: ```html ``` In the browser, you can attach the forEach method to any object. ```html ``` ## The General Idea (Why I thought this was worth sharing) The idea is to allow the callback to decide _at runtime_ whether the loop will be synchronous or asynchronous. By using `this` in a creative way (in situations where that value isn't already spoken for), an entire control API can be offered without over-complicating function signatures. ```javascript forEach(arr, function(item, index) { // Synchronous. }); forEach(arr, function(item, index) { // Only when `this.async` is called does iteration becomes asynchronous. The // loop won't be continued until the `done` function is executed. var done = this.async(); // Continue in one second. setTimeout(done, 1000); }); forEach(arr, function(item, index) { // Break out of synchronous iteration early by returning false. return index !== 1; }); forEach(arr, function(item, index) { // Break out of asynchronous iteration early... var done = this.async(); // ...by passing false to the done function. setTimeout(function() { done(index !== 1); }); }); ``` ## Examples See the unit tests for more examples. ```javascript // Generic "done" callback. function allDone(notAborted, arr) { console.log("done", notAborted, arr); } // Synchronous. forEach(["a", "b", "c"], function(item, index, arr) { console.log("each", item, index, arr); }, allDone); // logs: // each a 0 ["a", "b", "c"] // each b 1 ["a", "b", "c"] // each c 2 ["a", "b", "c"] // done true ["a", "b", "c"] // Synchronous with early abort. forEach(["a", "b", "c"], function(item, index, arr) { console.log("each", item, index, arr); if (item === "b") { return false; } }, allDone); // logs: // each a 0 ["a", "b", "c"] // each b 1 ["a", "b", "c"] // done false ["a", "b", "c"] // Asynchronous. forEach(["a", "b", "c"], function(item, index, arr) { console.log("each", item, index, arr); var done = this.async(); setTimeout(function() { done(); }, 500); }, allDone); // logs: // each a 0 ["a", "b", "c"] // each b 1 ["a", "b", "c"] // each c 2 ["a", "b", "c"] // done true ["a", "b", "c"] // Asynchronous with early abort. forEach(["a", "b", "c"], function(item, index, arr) { console.log("each", item, index, arr); var done = this.async(); setTimeout(function() { done(item !== "b"); }, 500); }, allDone); // logs: // each a 0 ["a", "b", "c"] // each b 1 ["a", "b", "c"] // done false ["a", "b", "c"] // Not actually asynchronous. forEach(["a", "b", "c"], function(item, index, arr) { console.log("each", item, index, arr); var done = this.async() done(); }, allDone); // logs: // each a 0 ["a", "b", "c"] // each b 1 ["a", "b", "c"] // each c 2 ["a", "b", "c"] // done true ["a", "b", "c"] // Not actually asynchronous with early abort. forEach(["a", "b", "c"], function(item, index, arr) { console.log("each", item, index, arr); var done = this.async(); done(item !== "b"); }, allDone); // logs: // each a 0 ["a", "b", "c"] // each b 1 ["a", "b", "c"] // done false ["a", "b", "c"] ``` ## Contributing In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [grunt](https://github.com/cowboy/grunt). _Also, please don't edit files in the "dist" subdirectory as they are generated via grunt. You'll find source code in the "lib" subdirectory!_ ## Release History 04/29/2013 v0.1.3 Removed hard Node.js version dependency. 11/17/2011 v0.1.2 Adding sparse array support. Invalid length properties are now sanitized. This closes issue #1 (like a boss). 11/11/2011 v0.1.1 Refactored code to be much simpler. Yay for unit tests! 11/11/2011 v0.1.0 Initial Release. ## License Copyright (c) 2012 "Cowboy" Ben Alman Licensed under the MIT license.