Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Refactored code to be much simpler. Yay for unit tests!

  • Loading branch information...
commit 60d948f5ea87c39c7de7c2414d978a7e0ae8ffb8 1 parent 02e9d3e
@cowboy authored
View
4 README.md
@@ -173,6 +173,10 @@ _Also, please don't edit files in the "dist" subdirectory as they are generated
v0.1.0
Initial Release.
+11/11/2011
+v0.1.1
+Refactored code to be much simpler. Yay for unit tests!
+
## License
Copyright (c) 2011 "Cowboy" Ben Alman
Dual licensed under the MIT and GPL licenses.
View
44 dist/ba-foreach.js
@@ -1,4 +1,4 @@
-/* JavaScript Sync/Async forEach - v0.1.0 - 11/11/2011
+/* JavaScript Sync/Async forEach - v0.1.1 - 11/11/2011
* http://github.com/cowboy/javascript-sync-async-foreach
* Copyright (c) 2011 "Cowboy" Ben Alman; Licensed MIT, GPL */
@@ -7,23 +7,21 @@
// Iterate synchronously or asynchronously.
exports.forEach = function(arr, eachFn, doneFn) {
var len = arr.length;
- var i = 0;
+ var i = -1;
// This IIFE is called once now, and then again, by name, for each loop
// iteration.
(function next(result) {
- // The async.async flag will be set to true if `this.async` is called
- // inside the `eachFn` callback. A few other properties will be maintained
- // as well, in order to handle the edge-case where the `this.async` done
- // function is called synchronously.
- var async = {};
+ // This flag will be set to true if `this.async` is called inside the
+ // eachFn` callback.
+ var async;
// Was false returned from the `eachFn` callback or passed to the
// `this.async` done function?
var abort = result === false;
// Exit if result passed to `this.async` done function or returned from
// the `eachFn` callback was false, or when done iterating.
- if (abort || i === len) {
+ if (abort || ++i === len) {
// If a `doneFn` callback was specified, invoke that now. Pass in a
// boolean value representing "not aborted" state along with the array.
if (doneFn) {
@@ -39,38 +37,14 @@
// If `this.async` is called inside the `eachFn` callback, set the async
// flag and return a function that can be used to continue iterating.
async: function() {
- async.async = true;
- // If, for some crazy reason, the `this.async` done function is called
- // synchronously, explicitly set the async flag to false and store a
- // result value that will be used to override the result returned from
- // the `eachFn` callback. Otherwise just call `next`.
- return function(result) {
- if (async.done) {
- next(result);
- } else {
- async.async = false;
- async.result = result;
- }
- };
+ async = true;
+ return next;
}
}, arr[i], i, arr);
- // Override the `eachFn` result if the `this.async` done function was
- // called synchronously.
- if (async.async === false) {
- result = async.result;
- }
-
- // `eachFn` has finished executing. If the `this.async` done function
- // executes after this point, it must be asynchronous.
- async.done = true;
-
- // Increment counter.
- i++;
-
// If the async flag wasn't set, continue by calling `next` synchronously,
// passing in the result of the `eachFn` callback.
- if (!async.async) {
+ if (!async) {
next(result);
}
}());
View
4 dist/ba-foreach.min.js
@@ -1,4 +1,4 @@
-/* JavaScript Sync/Async forEach - v0.1.0 - 11/11/2011
+/* JavaScript Sync/Async forEach - v0.1.1 - 11/11/2011
* http://github.com/cowboy/javascript-sync-async-foreach
* Copyright (c) 2011 "Cowboy" Ben Alman; Licensed MIT, GPL */
-(function(a){a.forEach=function(a,b,c){var d=a.length,e=0;(function f(g){var h={},j=g===!1;if(j||e===d){c&&c(!j,a);return}g=b.call({async:function(){return h.async=!0,function(a){h.done?f(a):(h.async=!1,h.result=a)}}},a[e],e,a),h.async===!1&&(g=h.result),h.done=!0,e++,h.async||f(g)})()}})(typeof exports=="object"&&exports||this)
+(function(a){a.forEach=function(a,b,c){var d=a.length,e=-1;(function f(g){var h,j=g===!1;if(j||++e===d){c&&c(!j,a);return}g=b.call({async:function(){return h=!0,f}},a[e],e,a),h||f(g)})()}})(typeof exports=="object"&&exports||this)
View
2  grunt.js
@@ -3,7 +3,7 @@ config.init({
meta: {
name: 'javascript-sync-async-foreach',
title: 'JavaScript Sync/Async forEach',
- version: '0.1.0',
+ version: '0.1.1',
description: 'An optionally-asynchronous forEach with an interesting interface.',
homepage: 'http://github.com/cowboy/javascript-sync-async-foreach',
author: '"Cowboy" Ben Alman',
View
42 lib/foreach.js
@@ -12,23 +12,21 @@
// Iterate synchronously or asynchronously.
exports.forEach = function(arr, eachFn, doneFn) {
var len = arr.length;
- var i = 0;
+ var i = -1;
// This IIFE is called once now, and then again, by name, for each loop
// iteration.
(function next(result) {
- // The async.async flag will be set to true if `this.async` is called
- // inside the `eachFn` callback. A few other properties will be maintained
- // as well, in order to handle the edge-case where the `this.async` done
- // function is called synchronously.
- var async = {};
+ // This flag will be set to true if `this.async` is called inside the
+ // eachFn` callback.
+ var async;
// Was false returned from the `eachFn` callback or passed to the
// `this.async` done function?
var abort = result === false;
// Exit if result passed to `this.async` done function or returned from
// the `eachFn` callback was false, or when done iterating.
- if (abort || i === len) {
+ if (abort || ++i === len) {
// If a `doneFn` callback was specified, invoke that now. Pass in a
// boolean value representing "not aborted" state along with the array.
if (doneFn) {
@@ -44,38 +42,14 @@
// If `this.async` is called inside the `eachFn` callback, set the async
// flag and return a function that can be used to continue iterating.
async: function() {
- async.async = true;
- // If, for some crazy reason, the `this.async` done function is called
- // synchronously, explicitly set the async flag to false and store a
- // result value that will be used to override the result returned from
- // the `eachFn` callback. Otherwise just call `next`.
- return function(result) {
- if (async.done) {
- next(result);
- } else {
- async.async = false;
- async.result = result;
- }
- };
+ async = true;
+ return next;
}
}, arr[i], i, arr);
- // Override the `eachFn` result if the `this.async` done function was
- // called synchronously.
- if (async.async === false) {
- result = async.result;
- }
-
- // `eachFn` has finished executing. If the `this.async` done function
- // executes after this point, it must be asynchronous.
- async.done = true;
-
- // Increment counter.
- i++;
-
// If the async flag wasn't set, continue by calling `next` synchronously,
// passing in the result of the `eachFn` callback.
- if (!async.async) {
+ if (!async) {
next(result);
}
}());
Please sign in to comment.
Something went wrong with that request. Please try again.