commit 4890f3ac92708cf145c624f3b1d04114eb2c7c2b Author: AJ ONeal Date: Tue Aug 6 02:44:04 2013 -0700 initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..48d3296 --- /dev/null +++ b/README.md @@ -0,0 +1,124 @@ +forEachAsync +=== + +v3.0 - Diet Cola Edition (not yet published to npm) + +Analogous to `[].forEach`, but handles items asynchronously with a final callback passed to `then`. + +This is the most essential piece of the [`ArrayAsync`](https://github.com/FuturesJS/ArrayAsync) package. + +Usage +=== + +It's as simple as you could guess: + +```javascript + // an asynchronous web request + function getPics(animal, cb) { + var flickerAPI = "http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?"; + $.getJSON( + flickerAPI + , { tags: thing + , tagmode: "any + , format: "json" + , success: function (data) { + console.log('teh animals:', data); + } + , complete: cb + } + ); + } + + // waits for one request to finish before beginning the next + forEachAsync(['dogs', 'cats', 'octocats'], function (next, element, index, array) { + getPics(element, next); + + // then after all of the elements have been handled + // the final callback fires to let you know it's all done + }).then(function () { + console.log('All requests have finished'); + }); +``` + + +Browser Installation +=== + +You can download and include `forEachAsync.js`: + +```html + +``` + +```javascript +(function () { + 'use strict'; + + var forEachAsync = window.forEachAsync + ; + + // do stuff ... +}()); +``` + +Or you can build it alongside other libraries: + +```bash +npm install -g pakmanager +npm install forEachAsync@3.x --save +pakmanager -e browser build +``` + +```html + +``` + +```javascript +(function () { + 'use strict'; + + var forEachAsync = require('forEachAsync').forEachAsync + ; + + // do stuff ... +}()); +``` + + +Node Installation +=== + +```bash +npm install --save forEachAsync@3.x +``` + +API +=== + +**`forEachAsync(array, callback[, thisArg])`** + +Parameters + + * `array` Array of elements to iterate over + * `callback` Function to execute for each element, takes 4 arguments + * `next` the function to call when the current element has been dealt with + * `element` a single element of the aforementioned array + * `index` the index of the current element + * `array` the same array mentioned above + * `thisArg` Object to use as `this` when executing `callback` + +**`forEachAsync#then(done)`** + +Parameters + + * `then` is in the return value of `forEachAsync` and accepts a final `done` callback. + * `done` called after `forEachAsync` is complete, takes no arguments + +Internal API +=== + +`forEachAsync.__BREAK` + +This is used internally for the purposes of the `ArrayAsync` library. + +Please don't `break` stuff; use `someAsync` or `everyAsync` instead. diff --git a/forEachAsync.js b/forEachAsync.js new file mode 100644 index 0000000..3ebf7e8 --- /dev/null +++ b/forEachAsync.js @@ -0,0 +1,34 @@ +/*jshint -W054 */ +(function (exports) { + "use strict"; + + function forEachAsync(arr, fn, thisArg) { + var dones = [] + , index = -1 + ; + + function next(BREAK, newArr) { + if (0 === arr.length || BREAK === forEachAsync.__BREAK) { + dones.forEach(function (done) { + done.call(thisArg, newArr); + }); + return; + } + + index += 1; + fn.call(thisArg, next, arr.shift(), index, arr); + } + + setTimeout(next, 4); + + return { + then: function (_done) { + dones.push(_done); + return this; + } + }; + } + forEachAsync.__BREAK = {}; + + exports.forEachAsync = forEachAsync; +}('undefined' !== typeof exports && exports || new Function('return this')()));