Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimized waterfall, parallel, et al. #1395

Merged
merged 12 commits into from Apr 7, 2017
256 changes: 108 additions & 148 deletions dist/async.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/async.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/async.min.map

Large diffs are not rendered by default.

15 changes: 9 additions & 6 deletions lib/apply.js
@@ -1,4 +1,4 @@
import rest from './internal/rest';
import slice from './internal/slice';

/**
* Creates a continuation function with some arguments already applied.
Expand All @@ -12,10 +12,11 @@ import rest from './internal/rest';
* @memberOf module:Utils
* @method
* @category Util
* @param {Function} function - The function you want to eventually apply all
* @param {Function} fn - The function you want to eventually apply all
* arguments to. Invokes with (arguments...).
* @param {...*} arguments... - Any number of arguments to automatically apply
* when the continuation is called.
* @returns {Function} the partially-applied function
* @example
*
* // using apply
Expand Down Expand Up @@ -44,8 +45,10 @@ import rest from './internal/rest';
* two
* three
*/
export default rest(function(fn, args) {
return rest(function(callArgs) {
export default function(fn/*, ...args*/) {
var args = slice(arguments, 1);
return function(/*callArgs*/) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: ...callArgs

var callArgs = slice(arguments);
return fn.apply(null, args.concat(callArgs));
});
});
};
};
14 changes: 7 additions & 7 deletions lib/auto.js
Expand Up @@ -4,8 +4,8 @@ import indexOf from 'lodash/_baseIndexOf';
import isArray from 'lodash/isArray';
import okeys from 'lodash/keys';
import noop from 'lodash/noop';
import rest from './internal/rest';

import slice from './internal/slice';
import once from './internal/once';
import onlyOnce from './internal/onlyOnce';
import wrapAsync from './internal/wrapAsync';
Expand Down Expand Up @@ -192,26 +192,26 @@ export default function (tasks, concurrency, callback) {
function runTask(key, task) {
if (hasError) return;

var taskCallback = onlyOnce(rest(function(err, args) {
var taskCallback = onlyOnce(function(err, result) {
runningTasks--;
if (args.length <= 1) {
args = args[0];
if (arguments.length > 2) {
result = slice(arguments, 1);
}
if (err) {
var safeResults = {};
forOwn(results, function(val, rkey) {
safeResults[rkey] = val;
});
safeResults[key] = args;
safeResults[key] = result;
hasError = true;
listeners = Object.create(null);

callback(err, safeResults);
} else {
results[key] = args;
results[key] = result;
taskComplete(key);
}
}));
});

runningTasks++;
var taskFn = wrapAsync(task[task.length - 1]);
Expand Down
8 changes: 4 additions & 4 deletions lib/compose.js
@@ -1,5 +1,5 @@
import seq from './seq';
import rest from './internal/rest';
import slice from './internal/slice';

/**
* Creates a function which is a composition of the passed asynchronous
Expand Down Expand Up @@ -36,6 +36,6 @@ import rest from './internal/rest';
* // result now equals 15
* });
*/
export default rest(function(args) {
return seq.apply(null, args.reverse());
});
export default function(/*...args*/) {
return seq.apply(null, slice(arguments).reverse());
};
13 changes: 7 additions & 6 deletions lib/constant.js
@@ -1,5 +1,4 @@
import rest from './internal/rest';
import initialParams from './internal/initialParams';
import slice from './internal/slice';

/**
* Returns a function that when called, calls-back with the values provided.
Expand Down Expand Up @@ -43,9 +42,11 @@ import initialParams from './internal/initialParams';
* //...
* }, callback);
*/
export default rest(function(values) {
export default function(/*...values*/) {
var values = slice(arguments);
var args = [null].concat(values);
return initialParams(function (ignoredArgs, callback) {
return function (/*...ignoredArgs, callback*/) {
var callback = arguments[arguments.length - 1];
return callback.apply(this, args);
});
});
};
};
9 changes: 5 additions & 4 deletions lib/doDuring.js
@@ -1,5 +1,5 @@
import noop from 'lodash/noop';
import rest from './internal/rest';
import slice from './internal/slice';
import onlyOnce from './internal/onlyOnce';
import wrapAsync from './internal/wrapAsync';

Expand Down Expand Up @@ -28,11 +28,12 @@ export default function doDuring(fn, test, callback) {
var _fn = wrapAsync(fn);
var _test = wrapAsync(test);

var next = rest(function(err, args) {
if (err) return callback(err);
function next(err/*, ...args*/) {
if (err) return callback(err);
var args = slice(arguments, 1);
args.push(check);
_test.apply(this, args);
});
};

function check(err, truth) {
if (err) return callback(err);
Expand Down
7 changes: 4 additions & 3 deletions lib/doWhilst.js
@@ -1,5 +1,5 @@
import noop from 'lodash/noop';
import rest from './internal/rest';
import slice from './internal/slice';

import onlyOnce from './internal/onlyOnce';
import wrapAsync from './internal/wrapAsync';
Expand Down Expand Up @@ -29,10 +29,11 @@ import wrapAsync from './internal/wrapAsync';
export default function doWhilst(iteratee, test, callback) {
callback = onlyOnce(callback || noop);
var _iteratee = wrapAsync(iteratee);
var next = rest(function(err, args) {
var next = function(err/*, ...args*/) {
if (err) return callback(err);
var args = slice(arguments, 1);
if (test.apply(this, args)) return _iteratee(next);
callback.apply(null, [null].concat(args));
});
};
_iteratee(next);
}
7 changes: 4 additions & 3 deletions lib/internal/applyEach.js
@@ -1,9 +1,10 @@
import rest from './rest';
import slice from './slice';
import initialParams from './initialParams';
import wrapAsync from './wrapAsync';

export default function applyEach(eachfn) {
return rest(function(fns, args) {
return function(fns/*, ...args*/) {
var args = slice(arguments, 1);
var go = initialParams(function(args, callback) {
var that = this;
return eachfn(fns, function (fn, cb) {
Expand All @@ -16,5 +17,5 @@ export default function applyEach(eachfn) {
else {
return go;
}
});
};
}
16 changes: 9 additions & 7 deletions lib/internal/consoleFunc.js
@@ -1,22 +1,24 @@
import arrayEach from 'lodash/_arrayEach';
import rest from './rest';
import slice from './slice';
import wrapAsync from './wrapAsync';

export default function consoleFunc(name) {
return rest(function (fn, args) {
wrapAsync(fn).apply(null, args.concat(rest(function (err, args) {
return function (fn/*, ...args*/) {
var args = slice(arguments, 1);
args.push(function (err/*, ...args*/) {
var args = slice(arguments, 1);
if (typeof console === 'object') {
if (err) {
if (console.error) {
console.error(err);
}
}
else if (console[name]) {
} else if (console[name]) {
arrayEach(args, function (x) {
console[name](x);
});
}
}
})));
});
})
wrapAsync(fn).apply(null, args);
};
}
7 changes: 4 additions & 3 deletions lib/internal/initialParams.js
@@ -1,8 +1,9 @@
import rest from './rest';
import slice from './slice';

export default function (fn) {
return rest(function (args/*..., callback*/) {
return function (/*...args, callback*/) {
var args = slice(arguments);
var callback = args.pop();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: pop can be avoided, slice(arguments, 0, -1), callback = arguments[arguments.length - 1]

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm gonna leave as-is. The streamlined version of slice doesn't support the 3rd end param.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good

fn.call(this, args, callback);
});
};
}
12 changes: 6 additions & 6 deletions lib/internal/parallel.js
@@ -1,20 +1,20 @@
import noop from 'lodash/noop';
import isArrayLike from 'lodash/isArrayLike';
import rest from './rest';
import slice from './slice';
import wrapAsync from './wrapAsync';

export default function _parallel(eachfn, tasks, callback) {
callback = callback || noop;
var results = isArrayLike(tasks) ? [] : {};

eachfn(tasks, function (task, key, callback) {
wrapAsync(task)(rest(function (err, args) {
if (args.length <= 1) {
args = args[0];
wrapAsync(task)(function (err, result) {
if (arguments.length > 2) {
result = slice(arguments, 1);
}
results[key] = args;
results[key] = result;
callback(err);
}));
});
}, function (err) {
callback(err, results);
});
Expand Down
11 changes: 5 additions & 6 deletions lib/internal/queue.js
@@ -1,7 +1,6 @@
import indexOf from 'lodash/_baseIndexOf';
import isArray from 'lodash/isArray';
import noop from 'lodash/noop';
import rest from './rest';

import onlyOnce from './onlyOnce';
import setImmediate from './setImmediate';
Expand Down Expand Up @@ -51,7 +50,7 @@ export default function queue(worker, concurrency, payload) {
}

function _next(tasks) {
return rest(function(args){
return function(err){
numRunning -= 1;

for (var i = 0, l = tasks.length; i < l; i++) {
Expand All @@ -61,10 +60,10 @@ export default function queue(worker, concurrency, payload) {
workersList.splice(index)
}

task.callback.apply(task, args);
task.callback.apply(task, arguments);

if (args[0] != null) {
q.error(args[0], task.data);
if (err != null) {
q.error(err, task.data);
}
}

Expand All @@ -76,7 +75,7 @@ export default function queue(worker, concurrency, payload) {
q.drain();
}
q.process();
});
};
}

var isProcessing = false;
Expand Down
8 changes: 0 additions & 8 deletions lib/internal/rest.js

This file was deleted.

7 changes: 4 additions & 3 deletions lib/internal/setImmediate.js
@@ -1,6 +1,6 @@
'use strict';

import rest from './rest';
import slice from './slice';

export var hasSetImmediate = typeof setImmediate === 'function' && setImmediate;
export var hasNextTick = typeof process === 'object' && typeof process.nextTick === 'function';
Expand All @@ -10,11 +10,12 @@ export function fallback(fn) {
}

export function wrap(defer) {
return rest(function (fn, args) {
return function (fn/*, ...args*/) {
var args = slice(arguments, 1);
defer(function () {
fn.apply(null, args);
});
});
};
}

var _defer;
Expand Down
9 changes: 9 additions & 0 deletions lib/internal/slice.js
@@ -0,0 +1,9 @@
export default function slice(arrayLike, start) {
start = start|0;
var newLen = Math.max(arrayLike.length - start, 0);
var newArr = Array(newLen);
for(var idx = 0; idx < newLen; idx++) {
newArr[idx] = arrayLike[start + idx];
}
return newArr;
}
7 changes: 4 additions & 3 deletions lib/memoize.js
@@ -1,5 +1,5 @@
import identity from 'lodash/identity';
import rest from './internal/rest';
import slice from './internal/slice';

import setImmediate from './internal/setImmediate';
import initialParams from './internal/initialParams';
Expand Down Expand Up @@ -61,14 +61,15 @@ export default function memoize(fn, hasher) {
queues[key].push(callback);
} else {
queues[key] = [callback];
_fn.apply(null, args.concat(rest(function(args) {
_fn.apply(null, args.concat(function(/*args*/) {
var args = slice(arguments);
memo[key] = args;
var q = queues[key];
delete queues[key];
for (var i = 0, l = q.length; i < l; i++) {
q[i].apply(null, args);
}
})));
}));
}
});
memoized.memo = memo;
Expand Down
5 changes: 2 additions & 3 deletions lib/reduceRight.js
@@ -1,6 +1,5 @@
import reduce from './reduce';

var slice = Array.prototype.slice;
import slice from './internal/slice';

/**
* Same as [`reduce`]{@link module:Collections.reduce}, only operates on `array` in reverse order.
Expand All @@ -25,6 +24,6 @@ var slice = Array.prototype.slice;
* (err, result).
*/
export default function reduceRight (array, memo, iteratee, callback) {
var reversed = slice.call(array).reverse();
var reversed = slice(array).reverse();
reduce(reversed, memo, iteratee, callback);
}