Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/cowboy/javascript-sync-async-foreach
An optionally-asynchronous forEach with an interesting interface.
https://github.com/cowboy/javascript-sync-async-foreach
Last synced: 4 days ago
JSON representation
An optionally-asynchronous forEach with an interesting interface.
- Host: GitHub
- URL: https://github.com/cowboy/javascript-sync-async-foreach
- Owner: cowboy
- License: mit
- Created: 2011-11-11T14:49:51.000Z (about 13 years ago)
- Default Branch: master
- Last Pushed: 2020-07-21T15:28:46.000Z (over 4 years ago)
- Last Synced: 2024-10-14T14:18:16.177Z (about 1 month ago)
- Language: JavaScript
- Homepage:
- Size: 120 KB
- Stars: 76
- Watchers: 4
- Forks: 11
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- License: LICENSE-MIT
Awesome Lists containing this project
README
# 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
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"]```
In the browser, you can attach the forEach method to any object.
```html
this.exports = Bocoup.utils;
Bocoup.utils.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"]```
## 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.