Skip to content

Commit

Permalink
ES6-ify codebase (caolan#1553)
Browse files Browse the repository at this point in the history
* cancelable foreach

* cancelable waterfall

* cancellable auto

* fix lint

* fix tests

* cancelable whilst/until/during/forever

* fix waterfall test.  It WILL get there

* docs

* use rest params instead of slice

* clean up internals

* remove property func

* clarify uses of createTester

* happy path async funtions in asyncify

* stop using arguments

* DLL to class

* moar arrows

* fix merge issues

* remove forOwn

* moar arrows

* fix merge mistake

* even more arrows, what can stop him

* mo more fn.apply(null,...)

* remove more spurious uses of apply

* update lint config

* just when you thought there couldn't possibly be more arrows

* use eslint:recommended

* even less uses or aguments

* get rid of prototype cuteness

* fix concat tests

* fix more tests
  • Loading branch information
aearly authored Jul 8, 2018
1 parent 6405b10 commit e475117
Show file tree
Hide file tree
Showing 125 changed files with 2,663 additions and 3,133 deletions.
6 changes: 6 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"ecmaVersion": 8,
"sourceType": "module"
},
"extends": "eslint:recommended",
"rules": {
"eqeqeq": 0,
"guard-for-in": 2,
Expand All @@ -19,6 +20,7 @@
"SwitchCase": 1
}
],
"no-console": 0,
"no-caller": 2,
"no-undef": 2,
"no-unused-vars": 2,
Expand All @@ -28,10 +30,14 @@
"last"
],
"semi": 0,
"prefer-arrow-callback": 2,
"arrow-spacing": 2,
"object-shorthand": 2,
"no-eq-null": 0,
"no-unused-expressions": 0,
"no-loop-func": 2,
"dot-notation": 0,
"no-trailing-spaces": 2,
"valid-jsdoc": ["error", {
"requireReturn": false,
"requireReturnDescription": false,
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ clean:
rm -rf perf/versions/

lint:
eslint $(LINT_FILES)
eslint --fix $(LINT_FILES)

# Compile the ES6 modules to singular bundles, and individual bundles
build-bundle: build-modules $(UMD_BUNDLE)
Expand Down
12 changes: 3 additions & 9 deletions lib/apply.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import slice from './internal/slice';

/**
* Creates a continuation function with some arguments already applied.
*
Expand Down Expand Up @@ -45,10 +43,6 @@ import slice from './internal/slice';
* two
* three
*/
export default function(fn/*, ...args*/) {
var args = slice(arguments, 1);
return function(/*callArgs*/) {
var callArgs = slice(arguments);
return fn.apply(null, args.concat(callArgs));
};
};
export default function(fn, ...args) {
return (...callArgs) => fn(...args,...callArgs);
}
31 changes: 20 additions & 11 deletions lib/asyncify.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import initialParams from './internal/initialParams';
import setImmediate from './internal/setImmediate';
import { isAsync } from './internal/wrapAsync'

/**
* Take a sync function and make it async, passing its return value to a
Expand Down Expand Up @@ -58,6 +59,14 @@ import setImmediate from './internal/setImmediate';
* q.push(files);
*/
export default function asyncify(func) {
if (isAsync(func)) {
return function (...args/*, callback*/) {
const callback = args.pop()
const promise = func.apply(this, args)
return handlePromise(promise, callback)
}
}

return initialParams(function (args, callback) {
var result;
try {
Expand All @@ -67,25 +76,25 @@ export default function asyncify(func) {
}
// if result is Promise object
if (result && typeof result.then === 'function') {
result.then(function(value) {
invokeCallback(callback, null, value);
}, function(err) {
invokeCallback(callback, err.message ? err : new Error(err));
});
return handlePromise(result, callback)
} else {
callback(null, result);
}
});
}

function handlePromise(promise, callback) {
return promise.then(value => {
invokeCallback(callback, null, value);
}, err => {
invokeCallback(callback, err.message ? err : new Error(err));
});
}

function invokeCallback(callback, error, value) {
try {
callback(error, value);
} catch (e) {
setImmediate(rethrow, e);
} catch (err) {
setImmediate(e => { throw e }, err);
}
}

function rethrow(error) {
throw error;
}
32 changes: 14 additions & 18 deletions lib/auto.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import noop from './internal/noop';

import forOwn from './internal/forOwn';
import slice from './internal/slice';
import once from './internal/once';
import onlyOnce from './internal/onlyOnce';
import wrapAsync from './internal/wrapAsync';
Expand Down Expand Up @@ -114,7 +112,8 @@ export default function (tasks, concurrency, callback) {
// without the possibility of returning to an ancestor task
var uncheckedDependencies = {};

forOwn(tasks, function (task, key) {
Object.keys(tasks).forEach(key => {
var task = tasks[key]
if (!Array.isArray(task)) {
// no dependencies
enqueueTask(key, [task]);
Expand All @@ -131,14 +130,14 @@ export default function (tasks, concurrency, callback) {
}
uncheckedDependencies[key] = remainingDependencies;

dependencies.forEach(function (dependencyName) {
dependencies.forEach(dependencyName => {
if (!tasks[dependencyName]) {
throw new Error('async.auto task `' + key +
'` has a non-existent dependency `' +
dependencyName + '` in ' +
dependencies.join(', '));
}
addListener(dependencyName, function () {
addListener(dependencyName, () => {
remainingDependencies--;
if (remainingDependencies === 0) {
enqueueTask(key, task);
Expand All @@ -151,9 +150,7 @@ export default function (tasks, concurrency, callback) {
processQueue();

function enqueueTask(key, task) {
readyTasks.push(function () {
runTask(key, task);
});
readyTasks.push(() => runTask(key, task));
}

function processQueue() {
Expand All @@ -179,29 +176,27 @@ export default function (tasks, concurrency, callback) {

function taskComplete(taskName) {
var taskListeners = listeners[taskName] || [];
taskListeners.forEach(function (fn) {
fn();
});
taskListeners.forEach(fn => fn());
processQueue();
}


function runTask(key, task) {
if (hasError) return;

var taskCallback = onlyOnce(function(err, result) {
var taskCallback = onlyOnce((err, ...result) => {
runningTasks--;
if (err === false) {
canceled = true
return
}
if (arguments.length > 2) {
result = slice(arguments, 1);
if (result.length < 2) {
result = result[0];
}
if (err) {
var safeResults = {};
forOwn(results, function(val, rkey) {
safeResults[rkey] = val;
Object.keys(results).forEach(rkey => {
safeResults[rkey] = results[rkey];
});
safeResults[key] = result;
hasError = true;
Expand Down Expand Up @@ -232,7 +227,7 @@ export default function (tasks, concurrency, callback) {
while (readyToCheck.length) {
currentTask = readyToCheck.pop();
counter++;
getDependents(currentTask).forEach(function (dependent) {
getDependents(currentTask).forEach(dependent => {
if (--uncheckedDependencies[dependent] === 0) {
readyToCheck.push(dependent);
}
Expand All @@ -248,7 +243,8 @@ export default function (tasks, concurrency, callback) {

function getDependents(taskName) {
var result = [];
forOwn(tasks, function (task, key) {
Object.keys(tasks).forEach(key => {
const task = tasks[key]
if (Array.isArray(task) && task.indexOf(taskName) >= 0) {
result.push(key);
}
Expand Down
18 changes: 8 additions & 10 deletions lib/autoInject.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import auto from './auto';
import forOwn from './internal/forOwn';
import wrapAsync from './internal/wrapAsync';
import { isAsync } from './internal/wrapAsync';

var FN_ARGS = /^(?:async\s+)?(function)?\s*[^\(]*\(\s*([^\)]*)\)/m;
var FN_ARGS = /^(?:async\s+)?(function)?\s*[^(]*\(\s*([^)]*)\)/m;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /(=.+)?(\s*)$/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
Expand All @@ -12,7 +11,7 @@ function parseParams(func) {
func = func.toString().replace(STRIP_COMMENTS, '');
func = func.match(FN_ARGS)[2].replace(' ', '');
func = func ? func.split(FN_ARG_SPLIT) : [];
func = func.map(function (arg){
func = func.map((arg) => {
return arg.replace(FN_ARG, '').trim();
});
return func;
Expand Down Expand Up @@ -103,16 +102,17 @@ function parseParams(func) {
export default function autoInject(tasks, callback) {
var newTasks = {};

forOwn(tasks, function (taskFn, key) {
Object.keys(tasks).forEach(key => {
var taskFn = tasks[key]
var params;
var fnIsAsync = isAsync(taskFn);
var hasNoDeps =
(!fnIsAsync && taskFn.length === 1) ||
(fnIsAsync && taskFn.length === 0);

if (Array.isArray(taskFn)) {
params = taskFn.slice(0, -1);
taskFn = taskFn[taskFn.length - 1];
params = [...taskFn];
taskFn = params.pop();

newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn);
} else if (hasNoDeps) {
Expand All @@ -131,11 +131,9 @@ export default function autoInject(tasks, callback) {
}

function newTask(results, taskCb) {
var newArgs = params.map(function (name) {
return results[name];
});
var newArgs = params.map(name => results[name])
newArgs.push(taskCb);
wrapAsync(taskFn).apply(null, newArgs);
wrapAsync(taskFn)(...newArgs);
}
});

Expand Down
7 changes: 3 additions & 4 deletions lib/compose.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import seq from './seq';
import slice from './internal/slice';

/**
* Creates a function which is a composition of the passed asynchronous
Expand Down Expand Up @@ -36,6 +35,6 @@ import slice from './internal/slice';
* // result now equals 15
* });
*/
export default function(/*...args*/) {
return seq.apply(null, slice(arguments).reverse());
};
export default function(...args) {
return seq(...args.reverse());
}
13 changes: 5 additions & 8 deletions lib/concatLimit.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import noop from './internal/noop';
import wrapAsync from './internal/wrapAsync';
import slice from './internal/slice';
import mapLimit from './mapLimit';

var _concat = Array.prototype.concat;

/**
* The same as [`concat`]{@link module:Collections.concat} but runs a maximum of `limit` async operations at a time.
*
Expand All @@ -26,16 +23,16 @@ var _concat = Array.prototype.concat;
export default function(coll, limit, iteratee, callback) {
callback = callback || noop;
var _iteratee = wrapAsync(iteratee);
mapLimit(coll, limit, function(val, callback) {
_iteratee(val, function(err /*, ...args*/) {
mapLimit(coll, limit, (val, callback) => {
_iteratee(val, (err, ...args) => {
if (err) return callback(err);
return callback(null, slice(arguments, 1));
return callback(null, args);
});
}, function(err, mapResults) {
}, (err, mapResults) => {
var result = [];
for (var i = 0; i < mapResults.length; i++) {
if (mapResults[i]) {
result = _concat.apply(result, mapResults[i]);
result = result.concat(...mapResults[i]);
}
}

Expand Down
14 changes: 5 additions & 9 deletions lib/constant.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import slice from './internal/slice';

/**
* Returns a function that when called, calls-back with the values provided.
* Useful as the first function in a [`waterfall`]{@link module:ControlFlow.waterfall}, or for plugging values in to
Expand Down Expand Up @@ -42,11 +40,9 @@ import slice from './internal/slice';
* //...
* }, callback);
*/
export default function(/*...values*/) {
var values = slice(arguments);
var args = [null].concat(values);
return function (/*...ignoredArgs, callback*/) {
var callback = arguments[arguments.length - 1];
return callback.apply(this, args);
export default function(...args) {
return function (...ignoredArgs/*, callback*/) {
var callback = ignoredArgs.pop();
return callback(null, ...args);
};
};
}
4 changes: 1 addition & 3 deletions lib/detect.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import identity from './internal/identity';
import createTester from './internal/createTester';
import doParallel from './internal/doParallel';
import findGetResult from './internal/findGetResult';

/**
* Returns the first value in `coll` that passes an async truth test. The
Expand Down Expand Up @@ -38,4 +36,4 @@ import findGetResult from './internal/findGetResult';
* // result now equals the first file in the list that exists
* });
*/
export default doParallel(createTester(identity, findGetResult));
export default doParallel(createTester(bool => bool, (res, item) => item));
4 changes: 1 addition & 3 deletions lib/detectLimit.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import identity from './internal/identity';
import createTester from './internal/createTester';
import doParallelLimit from './internal/doParallelLimit';
import findGetResult from './internal/findGetResult';

/**
* The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a
Expand All @@ -25,4 +23,4 @@ import findGetResult from './internal/findGetResult';
* (iteratee) or the value `undefined` if none passed. Invoked with
* (err, result).
*/
export default doParallelLimit(createTester(identity, findGetResult));
export default doParallelLimit(createTester(bool => bool, (res, item) => item));
9 changes: 3 additions & 6 deletions lib/doDuring.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import noop from './internal/noop';
import slice from './internal/slice';
import onlyOnce from './internal/onlyOnce';
import wrapAsync from './internal/wrapAsync';

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

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

function check(err, truth) {
if (err) return callback(err);
Expand Down
Loading

0 comments on commit e475117

Please sign in to comment.