Skip to content

Commit

Permalink
Merge pull request #1246 from caolan/fast-path-eachOf
Browse files Browse the repository at this point in the history
Fast path eachOf array case
  • Loading branch information
megawac committed Jul 21, 2016
2 parents 72a7810 + 910106f commit 0f75578
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 22 deletions.
8 changes: 5 additions & 3 deletions lib/each.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import eachLimit from './eachLimit';
import doLimit from './internal/doLimit';
import eachOf from './eachOf';
import withoutIndex from './internal/withoutIndex';

/**
* Applies the function `iteratee` to each item in `coll`, in parallel.
Expand Down Expand Up @@ -60,4 +60,6 @@ import doLimit from './internal/doLimit';
* }
* });
*/
export default doLimit(eachLimit, Infinity);
export default function eachLimit(coll, iteratee, callback) {
eachOf(coll, withoutIndex(iteratee), callback);
}
36 changes: 35 additions & 1 deletion lib/eachOf.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,36 @@
import isArrayLike from 'lodash/isArrayLike';

import eachOfLimit from './eachOfLimit';
import doLimit from './internal/doLimit';
import noop from 'lodash/noop';
import once from 'lodash/once';
import onlyOnce from './internal/onlyOnce';

// eachOf implementation optimized for array-likes
function eachOfArrayLike(coll, iteratee, callback) {
callback = once(callback || noop);
var index = 0,
completed = 0,
length = coll.length;
if (length === 0) {
callback(null);
}

function iteratorCallback(err) {
if (err) {
callback(err);
} else if (++completed === length) {
callback(null);
}
}

for (; index < length; index++) {
iteratee(coll[index], index, onlyOnce(iteratorCallback));
}
}

// a generic version of eachOf which can handle array, object, and iterator cases.
var eachOfGeneric = doLimit(eachOfLimit, Infinity);

/**
* Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument
Expand Down Expand Up @@ -42,4 +73,7 @@ import doLimit from './internal/doLimit';
* doSomethingWith(configs);
* });
*/
export default doLimit(eachOfLimit, Infinity);
export default function(coll, iteratee, callback) {
var eachOfImplementation = isArrayLike(coll) ? eachOfArrayLike : eachOfGeneric;
eachOfImplementation(coll, iteratee, callback);
}
7 changes: 4 additions & 3 deletions lib/every.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import everyLimit from './everyLimit';
import doLimit from './internal/doLimit';
import createTester from './internal/createTester';
import eachOf from './eachOf';
import notId from './internal/notId';

/**
* Returns `true` if every element in `coll` satisfies an async test. If any
Expand Down Expand Up @@ -29,4 +30,4 @@ import doLimit from './internal/doLimit';
* // if result is true then every file exists
* });
*/
export default doLimit(everyLimit, Infinity);
export default createTester(eachOf, notId, notId);
6 changes: 3 additions & 3 deletions lib/filter.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import filterLimit from './filterLimit';
import doLimit from './internal/doLimit';
import filter from './internal/filter';
import doParallel from './internal/doParallel';

/**
* Returns a new array of all the values in `coll` which pass an async truth
Expand Down Expand Up @@ -28,4 +28,4 @@ import doLimit from './internal/doLimit';
* // results now equals an array of the existing files
* });
*/
export default doLimit(filterLimit, Infinity);
export default doParallel(filter);
6 changes: 3 additions & 3 deletions lib/map.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import mapLimit from './mapLimit';
import doLimit from './internal/doLimit';
import doParallel from './internal/doParallel';
import map from './internal/map';

/**
* Produces a new collection of values by mapping each value in `coll` through
Expand Down Expand Up @@ -37,4 +37,4 @@ import doLimit from './internal/doLimit';
* // results is now an array of stats for each file
* });
*/
export default doLimit(mapLimit, Infinity);
export default doParallel(map);
8 changes: 5 additions & 3 deletions lib/parallel.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import parallelLimit from './parallelLimit';
import doLimit from './internal/doLimit';
import eachOf from './eachOf';
import parallel from './internal/parallel';

/**
* Run the `tasks` collection of functions in parallel, without waiting until
Expand Down Expand Up @@ -67,4 +67,6 @@ import doLimit from './internal/doLimit';
* // results is now equals to: {one: 1, two: 2}
* });
*/
export default doLimit(parallelLimit, Infinity);
export default function parallelLimit(tasks, callback) {
parallel(eachOf, tasks, callback);
}
6 changes: 3 additions & 3 deletions lib/reject.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import rejectLimit from './rejectLimit';
import doLimit from './internal/doLimit';
import reject from './internal/reject';
import doParallel from './internal/doParallel';

/**
* The opposite of [`filter`]{@link module:Collections.filter}. Removes values that pass an `async` truth test.
Expand Down Expand Up @@ -27,4 +27,4 @@ import doLimit from './internal/doLimit';
* createFiles(results);
* });
*/
export default doLimit(rejectLimit, Infinity);
export default doParallel(reject);
7 changes: 4 additions & 3 deletions lib/some.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import someLimit from './someLimit';
import doLimit from './internal/doLimit';
import createTester from './internal/createTester';
import eachOf from './eachOf';
import identity from 'lodash/identity';

/**
* Returns `true` if at least one element in the `coll` satisfies an async test.
Expand Down Expand Up @@ -31,4 +32,4 @@ import doLimit from './internal/doLimit';
* // if result is true then at least one of the files exists
* });
*/
export default doLimit(someLimit, Infinity);
export default createTester(eachOf, Boolean, identity);
13 changes: 13 additions & 0 deletions mocha_test/eachOf.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
var async = require('../lib');
var expect = require('chai').expect;
var assert = require('assert');
var _ = require('lodash');

describe("eachOf", function() {

Expand Down Expand Up @@ -261,6 +262,18 @@ describe("eachOf", function() {
setTimeout(done, 25);
});

it('forEachOfLimit no limit', function(done) {
var count = 0;
async.forEachOfLimit(_.range(100), Infinity, function(x, i, callback){
count++;
callback();
}, function(err){
if (err) throw err;
expect(count).to.equal(100);
});
setTimeout(done, 25);
});

it('forEachOfLimit error', function(done) {
var obj = { a: 1, b: 2, c: 3, d: 4, e: 5 };
var call_order = [];
Expand Down

0 comments on commit 0f75578

Please sign in to comment.