You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
9184 lines
230 KiB
9184 lines
230 KiB
(function(global, factory) { |
|
/*jshint -W030 */ |
|
'use strict'; |
|
typeof exports === 'object' && typeof module !== 'undefined' |
|
? factory(exports) |
|
: typeof define === 'function' && define.amd |
|
? define(['exports'], factory) |
|
: global.async |
|
? factory((global.neo_async = global.neo_async || {})) |
|
: factory((global.async = global.async || {})); |
|
})(this, function(exports) { |
|
'use strict'; |
|
|
|
var noop = function noop() {}; |
|
var throwError = function throwError() { |
|
throw new Error('Callback was already called.'); |
|
}; |
|
|
|
var DEFAULT_TIMES = 5; |
|
var DEFAULT_INTERVAL = 0; |
|
|
|
var obj = 'object'; |
|
var func = 'function'; |
|
var isArray = Array.isArray; |
|
var nativeKeys = Object.keys; |
|
var nativePush = Array.prototype.push; |
|
var iteratorSymbol = typeof Symbol === func && Symbol.iterator; |
|
|
|
var nextTick, asyncNextTick, asyncSetImmediate; |
|
createImmediate(); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace each |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.each(array, iterator, function(err, res) { |
|
* console.log(res); // undefined |
|
* console.log(order); // [1, 2, 3] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.each(array, iterator, function(err, res) { |
|
* console.log(res); // undefined |
|
* console.log(order); // [[1, 0], [2, 2], [3, 1]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.each(object, iterator, function(err, res) { |
|
* console.log(res); // undefined |
|
* console.log(order); // [1, 2, 3] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.each(object, iterator, function(err, res) { |
|
* console.log(res); // undefined |
|
* console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // break |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num !== 2); |
|
* }, num * 10); |
|
* }; |
|
* async.each(array, iterator, function(err, res) { |
|
* console.log(res); // undefined |
|
* console.log(order); // [1, 2] |
|
* }); |
|
* |
|
*/ |
|
var each = createEach(arrayEach, baseEach, symbolEach); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace map |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.map(array, iterator, function(err, res) { |
|
* console.log(res); // [1, 3, 2]; |
|
* console.log(order); // [1, 2, 3] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.map(array, iterator, function(err, res) { |
|
* console.log(res); // [1, 3, 2] |
|
* console.log(order); // [[1, 0], [2, 2], [3, 1]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.map(object, iterator, function(err, res) { |
|
* console.log(res); // [1, 3, 2] |
|
* console.log(order); // [1, 2, 3] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.map(object, iterator, function(err, res) { |
|
* console.log(res); // [1, 3, 2] |
|
* console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']] |
|
* }); |
|
* |
|
*/ |
|
var map = createMap(arrayEachIndex, baseEachIndex, symbolEachIndex, true); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace mapValues |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.mapValues(array, iterator, function(err, res) { |
|
* console.log(res); // { '0': 1, '1': 3, '2': 2 } |
|
* console.log(order); // [1, 2, 3] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.mapValues(array, iterator, function(err, res) { |
|
* console.log(res); // { '0': 1, '1': 3, '2': 2 } |
|
* console.log(order); // [[1, 0], [2, 2], [3, 1]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.mapValues(object, iterator, function(err, res) { |
|
* console.log(res); // { a: 1, b: 3, c: 2 } |
|
* console.log(order); // [1, 2, 3] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.mapValues(object, iterator, function(err, res) { |
|
* console.log(res); // { a: 1, b: 3, c: 2 } |
|
* console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']] |
|
* }); |
|
* |
|
*/ |
|
var mapValues = createMap(arrayEachIndex, baseEachKey, symbolEachKey, false); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace filter |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.filter(array, iterator, function(err, res) { |
|
* console.log(res); // [1, 3]; |
|
* console.log(order); // [1, 2, 3] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.filter(array, iterator, function(err, res) { |
|
* console.log(res); // [1, 3]; |
|
* console.log(order); // [[1, 0], [2, 2], [3, 1]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.filter(object, iterator, function(err, res) { |
|
* console.log(res); // [1, 3]; |
|
* console.log(order); // [1, 2, 3] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.filter(object, iterator, function(err, res) { |
|
* console.log(res); // [1, 3]; |
|
* console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']] |
|
* }); |
|
* |
|
*/ |
|
var filter = createFilter(arrayEachIndexValue, baseEachIndexValue, symbolEachIndexValue, true); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace filterSeries |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.filterSeries(array, iterator, function(err, res) { |
|
* console.log(res); // [1, 3]; |
|
* console.log(order); // [1, 3, 2] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.filterSeries(array, iterator, function(err, res) { |
|
* console.log(res); // [1, 3] |
|
* console.log(order); // [[1, 0], [3, 1], [2, 2]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.filterSeries(object, iterator, function(err, res) { |
|
* console.log(res); // [1, 3] |
|
* console.log(order); // [1, 3, 2] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.filterSeries(object, iterator, function(err, res) { |
|
* console.log(res); // [1, 3] |
|
* console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']] |
|
* }); |
|
* |
|
*/ |
|
var filterSeries = createFilterSeries(true); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace filterLimit |
|
* @param {Array|Object} collection |
|
* @param {number} limit - limit >= 1 |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.filterLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // [1, 5, 3] |
|
* console.log(order); // [1, 3, 5, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.filterLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // [1, 5, 3] |
|
* console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.filterLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // [1, 5, 3] |
|
* console.log(order); // [1, 3, 5, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.filterLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // [1, 5, 3] |
|
* console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']] |
|
* }); |
|
* |
|
*/ |
|
var filterLimit = createFilterLimit(true); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace reject |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.reject(array, iterator, function(err, res) { |
|
* console.log(res); // [2]; |
|
* console.log(order); // [1, 2, 3] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.reject(array, iterator, function(err, res) { |
|
* console.log(res); // [2]; |
|
* console.log(order); // [[1, 0], [2, 2], [3, 1]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.reject(object, iterator, function(err, res) { |
|
* console.log(res); // [2]; |
|
* console.log(order); // [1, 2, 3] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.reject(object, iterator, function(err, res) { |
|
* console.log(res); // [2]; |
|
* console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']] |
|
* }); |
|
* |
|
*/ |
|
var reject = createFilter(arrayEachIndexValue, baseEachIndexValue, symbolEachIndexValue, false); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace rejectSeries |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.rejectSeries(array, iterator, function(err, res) { |
|
* console.log(res); // [2]; |
|
* console.log(order); // [1, 3, 2] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.rejectSeries(object, iterator, function(err, res) { |
|
* console.log(res); // [2]; |
|
* console.log(order); // [1, 3, 2] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.rejectSeries(object, iterator, function(err, res) { |
|
* console.log(res); // [2]; |
|
* console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']] |
|
* }); |
|
* |
|
*/ |
|
var rejectSeries = createFilterSeries(false); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace rejectLimit |
|
* @param {Array|Object} collection |
|
* @param {number} limit - limit >= 1 |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.rejectLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // [4, 2] |
|
* console.log(order); // [1, 3, 5, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.rejectLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // [4, 2] |
|
* console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.rejectLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // [4, 2] |
|
* console.log(order); // [1, 3, 5, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.rejectLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // [4, 2] |
|
* console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']] |
|
* }); |
|
* |
|
*/ |
|
var rejectLimit = createFilterLimit(false); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace detect |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.detect(array, iterator, function(err, res) { |
|
* console.log(res); // 1 |
|
* console.log(order); // [1] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.detect(array, iterator, function(err, res) { |
|
* console.log(res); // 1 |
|
* console.log(order); // [[1, 0]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.detect(object, iterator, function(err, res) { |
|
* console.log(res); // 1 |
|
* console.log(order); // [1] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.detect(object, iterator, function(err, res) { |
|
* console.log(res); // 1 |
|
* console.log(order); // [[1, 'a']] |
|
* }); |
|
* |
|
*/ |
|
var detect = createDetect(arrayEachValue, baseEachValue, symbolEachValue, true); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace detectSeries |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.detectSeries(array, iterator, function(err, res) { |
|
* console.log(res); // 1 |
|
* console.log(order); // [1] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.detectSeries(array, iterator, function(err, res) { |
|
* console.log(res); // 1 |
|
* console.log(order); // [[1, 0]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.detectSeries(object, iterator, function(err, res) { |
|
* console.log(res); // 1 |
|
* console.log(order); // [1] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.detectSeries(object, iterator, function(err, res) { |
|
* console.log(res); // 1 |
|
* console.log(order); // [[1, 'a']] |
|
* }); |
|
* |
|
*/ |
|
var detectSeries = createDetectSeries(true); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace detectLimit |
|
* @param {Array|Object} collection |
|
* @param {number} limit - limit >= 1 |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.detectLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // 1 |
|
* console.log(order); // [1] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.detectLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // 1 |
|
* console.log(order); // [[1, 0]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.detectLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // 1 |
|
* console.log(order); // [1] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.detectLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // 1 |
|
* console.log(order); // [[1, 'a']] |
|
* }); |
|
* |
|
*/ |
|
var detectLimit = createDetectLimit(true); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace every |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.every(array, iterator, function(err, res) { |
|
* console.log(res); // false |
|
* console.log(order); // [1, 2] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.every(array, iterator, function(err, res) { |
|
* console.log(res); // false |
|
* console.log(order); // [[1, 0], [2, 2]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.every(object, iterator, function(err, res) { |
|
* console.log(res); // false |
|
* console.log(order); // [1, 2] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.every(object, iterator, function(err, res) { |
|
* console.log(res); // false |
|
* console.log(order); // [[1, 'a'], [2, 'c']] |
|
* }); |
|
* |
|
*/ |
|
var every = createEvery(arrayEachValue, baseEachValue, symbolEachValue); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace everySeries |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.everySeries(array, iterator, function(err, res) { |
|
* console.log(res); // false |
|
* console.log(order); // [1, 3, 2] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.everySeries(array, iterator, function(err, res) { |
|
* console.log(res); // false |
|
* console.log(order); // [[1, 0], [3, 1], [2, 2]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.everySeries(object, iterator, function(err, res) { |
|
* console.log(res); // false |
|
* console.log(order); // [1, 3, 2] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.everySeries(object, iterator, function(err, res) { |
|
* console.log(res); // false |
|
* console.log(order); // [[1, 'a'], [3, 'b'] [2, 'c']] |
|
* }); |
|
* |
|
*/ |
|
var everySeries = createEverySeries(); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace everyLimit |
|
* @param {Array|Object} collection |
|
* @param {number} limit - limit >= 1 |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.everyLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // false |
|
* console.log(order); // [1, 3, 5, 2] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.everyLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // false |
|
* console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.everyLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // false |
|
* console.log(order); // [1, 3, 5, 2] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.everyLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // false |
|
* console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e']] |
|
* }); |
|
* |
|
*/ |
|
var everyLimit = createEveryLimit(); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace pick |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2, 4]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.pick(array, iterator, function(err, res) { |
|
* console.log(res); // { '0': 1, '1': 3 } |
|
* console.log(order); // [1, 2, 3, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2, 4]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.pick(array, iterator, function(err, res) { |
|
* console.log(res); // { '0': 1, '1': 3 } |
|
* console.log(order); // [[0, 1], [2, 2], [3, 1], [4, 3]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2, d: 4 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.pick(object, iterator, function(err, res) { |
|
* console.log(res); // { a: 1, b: 3 } |
|
* console.log(order); // [1, 2, 3, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2, d: 4 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.pick(object, iterator, function(err, res) { |
|
* console.log(res); // { a: 1, b: 3 } |
|
* console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b'], [4, 'd']] |
|
* }); |
|
* |
|
*/ |
|
var pick = createPick(arrayEachIndexValue, baseEachKeyValue, symbolEachKeyValue, true); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace pickSeries |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2, 4]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.pickSeries(array, iterator, function(err, res) { |
|
* console.log(res); // { '0': 1, '1': 3 } |
|
* console.log(order); // [1, 3, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2, 4]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.pickSeries(array, iterator, function(err, res) { |
|
* console.log(res); // { '0': 1, '1': 3 } |
|
* console.log(order); // [[0, 1], [3, 1], [2, 2], [4, 3]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2, d: 4 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.pickSeries(object, iterator, function(err, res) { |
|
* console.log(res); // { a: 1, b: 3 } |
|
* console.log(order); // [1, 3, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2, d: 4 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.pickSeries(object, iterator, function(err, res) { |
|
* console.log(res); // { a: 1, b: 3 } |
|
* console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c'], [4, 'd']] |
|
* }); |
|
* |
|
*/ |
|
var pickSeries = createPickSeries(true); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace pickLimit |
|
* @param {Array|Object} collection |
|
* @param {number} limit - limit >= 1 |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.pickLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // { '0': 1, '1': 5, '2': 3 } |
|
* console.log(order); // [1, 3, 5, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.pickLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // { '0': 1, '1': 5, '2': 3 } |
|
* console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.pickLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // { a: 1, b: 5, c: 3 } |
|
* console.log(order); // [1, 3, 5, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.pickLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // { a: 1, b: 5, c: 3 } |
|
* console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']] |
|
* }); |
|
* |
|
*/ |
|
var pickLimit = createPickLimit(true); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace omit |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2, 4]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.omit(array, iterator, function(err, res) { |
|
* console.log(res); // { '2': 2, '3': 4 } |
|
* console.log(order); // [1, 2, 3, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2, 4]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.omit(array, iterator, function(err, res) { |
|
* console.log(res); // { '2': 2, '3': 4 } |
|
* console.log(order); // [[0, 1], [2, 2], [3, 1], [4, 3]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2, d: 4 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.omit(object, iterator, function(err, res) { |
|
* console.log(res); // { c: 2, d: 4 } |
|
* console.log(order); // [1, 2, 3, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2, d: 4 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.omit(object, iterator, function(err, res) { |
|
* console.log(res); // { c: 2, d: 4 } |
|
* console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b'], [4, 'd']] |
|
* }); |
|
* |
|
*/ |
|
var omit = createPick(arrayEachIndexValue, baseEachKeyValue, symbolEachKeyValue, false); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace omitSeries |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2, 4]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.omitSeries(array, iterator, function(err, res) { |
|
* console.log(res); // { '2': 2, '3': 4 } |
|
* console.log(order); // [1, 3, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2, 4]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.omitSeries(array, iterator, function(err, res) { |
|
* console.log(res); // { '2': 2, '3': 4 } |
|
* console.log(order); // [[0, 1], [3, 1], [2, 2], [4, 3]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2, d: 4 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.omitSeries(object, iterator, function(err, res) { |
|
* console.log(res); // { c: 2, d: 4 } |
|
* console.log(order); // [1, 3, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2, d: 4 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.omitSeries(object, iterator, function(err, res) { |
|
* console.log(res); // { c: 2, d: 4 } |
|
* console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c'], [4, 'd']] |
|
* }); |
|
* |
|
*/ |
|
var omitSeries = createPickSeries(false); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace omitLimit |
|
* @param {Array|Object} collection |
|
* @param {number} limit - limit >= 1 |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.omitLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // { '3': 4, '4': 2 } |
|
* console.log(order); // [1, 3, 5, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.omitLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // { '3': 4, '4': 2 } |
|
* console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.omitLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // { d: 4, e: 2 } |
|
* console.log(order); // [1, 3, 5, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.omitLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // { d: 4, e: 2 } |
|
* console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']] |
|
* }); |
|
* |
|
*/ |
|
var omitLimit = createPickLimit(false); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace transform |
|
* @param {Array|Object} collection |
|
* @param {Array|Object|Function} [accumulator] |
|
* @param {Function} [iterator] |
|
* @param {Function} [callback] |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var collection = [1, 3, 2, 4]; |
|
* var iterator = function(result, num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* result.push(num) |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.transform(collection, iterator, function(err, res) { |
|
* console.log(res); // [1, 2, 3, 4] |
|
* console.log(order); // [1, 2, 3, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index and accumulator |
|
* var order = []; |
|
* var collection = [1, 3, 2, 4]; |
|
* var iterator = function(result, num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* result[index] = num; |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.transform(collection, {}, iterator, function(err, res) { |
|
* console.log(res); // { '0': 1, '1': 3, '2': 2, '3': 4 } |
|
* console.log(order); // [[1, 0], [2, 2], [3, 1], [4, 3]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with accumulator |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2, d: 4 }; |
|
* var iterator = function(result, num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* result.push(num); |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.transform(collection, [], iterator, function(err, res) { |
|
* console.log(res); // [1, 2, 3, 4] |
|
* console.log(order); // [1, 2, 3, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2, d: 4 }; |
|
* var iterator = function(result, num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* result[key] = num; |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.transform(collection, iterator, function(err, res) { |
|
* console.log(res); // { a: 1, b: 3, c: 2, d: 4 } |
|
* console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b'], [4, 'd']] |
|
* }); |
|
* |
|
*/ |
|
var transform = createTransform(arrayEachResult, baseEachResult, symbolEachResult); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace sortBy |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.sortBy(array, iterator, function(err, res) { |
|
* console.log(res); // [1, 2, 3]; |
|
* console.log(order); // [1, 2, 3] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.sortBy(array, iterator, function(err, res) { |
|
* console.log(res); // [1, 2, 3] |
|
* console.log(order); // [[1, 0], [2, 2], [3, 1]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.sortBy(object, iterator, function(err, res) { |
|
* console.log(res); // [1, 2, 3] |
|
* console.log(order); // [1, 2, 3] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.sortBy(object, iterator, function(err, res) { |
|
* console.log(res); // [1, 2, 3] |
|
* console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']] |
|
* }); |
|
* |
|
*/ |
|
var sortBy = createSortBy(arrayEachIndexValue, baseEachIndexValue, symbolEachIndexValue); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace concat |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, [num]); |
|
* }, num * 10); |
|
* }; |
|
* async.concat(array, iterator, function(err, res) { |
|
* console.log(res); // [1, 2, 3]; |
|
* console.log(order); // [1, 2, 3] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, [num]); |
|
* }, num * 10); |
|
* }; |
|
* async.concat(array, iterator, function(err, res) { |
|
* console.log(res); // [1, 2, 3] |
|
* console.log(order); // [[1, 0], [2, 2], [3, 1]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, [num]); |
|
* }, num * 10); |
|
* }; |
|
* async.concat(object, iterator, function(err, res) { |
|
* console.log(res); // [1, 2, 3] |
|
* console.log(order); // [1, 2, 3] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, [num]); |
|
* }, num * 10); |
|
* }; |
|
* async.concat(object, iterator, function(err, res) { |
|
* console.log(res); // [1, 2, 3] |
|
* console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']] |
|
* }); |
|
* |
|
*/ |
|
var concat = createConcat(arrayEachIndex, baseEachIndex, symbolEachIndex); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace groupBy |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [4.2, 6.4, 6.1]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, Math.floor(num)); |
|
* }, num * 10); |
|
* }; |
|
* async.groupBy(array, iterator, function(err, res) { |
|
* console.log(res); // { '4': [4.2], '6': [6.1, 6.4] } |
|
* console.log(order); // [4.2, 6.1, 6.4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [4.2, 6.4, 6.1]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, Math.floor(num)); |
|
* }, num * 10); |
|
* }; |
|
* async.groupBy(array, iterator, function(err, res) { |
|
* console.log(res); // { '4': [4.2], '6': [6.1, 6.4] } |
|
* console.log(order); // [[4.2, 0], [6.1, 2], [6.4, 1]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 4.2, b: 6.4, c: 6.1 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, Math.floor(num)); |
|
* }, num * 10); |
|
* }; |
|
* async.groupBy(object, iterator, function(err, res) { |
|
* console.log(res); // { '4': [4.2], '6': [6.1, 6.4] } |
|
* console.log(order); // [4.2, 6.1, 6.4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 4.2, b: 6.4, c: 6.1 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, Math.floor(num)); |
|
* }, num * 10); |
|
* }; |
|
* async.groupBy(object, iterator, function(err, res) { |
|
* console.log(res); // { '4': [4.2], '6': [6.1, 6.4] } |
|
* console.log(order); // [[4.2, 'a'], [6.1, 'c'], [6.4, 'b']] |
|
* }); |
|
* |
|
*/ |
|
var groupBy = createGroupBy(arrayEachValue, baseEachValue, symbolEachValue); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace parallel |
|
* @param {Array|Object} tasks - functions |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* var order = []; |
|
* var tasks = [ |
|
* function(done) { |
|
* setTimeout(function() { |
|
* order.push(1); |
|
* done(null, 1); |
|
* }, 10); |
|
* }, |
|
* function(done) { |
|
* setTimeout(function() { |
|
* order.push(2); |
|
* done(null, 2); |
|
* }, 30); |
|
* }, |
|
* function(done) { |
|
* setTimeout(function() { |
|
* order.push(3); |
|
* done(null, 3); |
|
* }, 40); |
|
* }, |
|
* function(done) { |
|
* setTimeout(function() { |
|
* order.push(4); |
|
* done(null, 4); |
|
* }, 20); |
|
* } |
|
* ]; |
|
* async.parallel(tasks, function(err, res) { |
|
* console.log(res); // [1, 2, 3, 4]; |
|
* console.log(order); // [1, 4, 2, 3] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* var order = []; |
|
* var tasks = { |
|
* 'a': function(done) { |
|
* setTimeout(function() { |
|
* order.push(1); |
|
* done(null, 1); |
|
* }, 10); |
|
* }, |
|
* 'b': function(done) { |
|
* setTimeout(function() { |
|
* order.push(2); |
|
* done(null, 2); |
|
* }, 30); |
|
* }, |
|
* 'c': function(done) { |
|
* setTimeout(function() { |
|
* order.push(3); |
|
* done(null, 3); |
|
* }, 40); |
|
* }, |
|
* 'd': function(done) { |
|
* setTimeout(function() { |
|
* order.push(4); |
|
* done(null, 4); |
|
* }, 20); |
|
* } |
|
* }; |
|
* async.parallel(tasks, function(err, res) { |
|
* console.log(res); // { a: 1, b: 2, c: 3, d:4 } |
|
* console.log(order); // [1, 4, 2, 3] |
|
* }); |
|
* |
|
*/ |
|
var parallel = createParallel(arrayEachFunc, baseEachFunc); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace applyEach |
|
*/ |
|
var applyEach = createApplyEach(map); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace applyEachSeries |
|
*/ |
|
var applyEachSeries = createApplyEach(mapSeries); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace log |
|
*/ |
|
var log = createLogger('log'); |
|
|
|
/** |
|
* @memberof async |
|
* @namespace dir |
|
*/ |
|
var dir = createLogger('dir'); |
|
|
|
/** |
|
* @version 2.6.2 |
|
* @namespace async |
|
*/ |
|
var index = { |
|
VERSION: '2.6.2', |
|
|
|
// Collections |
|
each: each, |
|
eachSeries: eachSeries, |
|
eachLimit: eachLimit, |
|
forEach: each, |
|
forEachSeries: eachSeries, |
|
forEachLimit: eachLimit, |
|
eachOf: each, |
|
eachOfSeries: eachSeries, |
|
eachOfLimit: eachLimit, |
|
forEachOf: each, |
|
forEachOfSeries: eachSeries, |
|
forEachOfLimit: eachLimit, |
|
map: map, |
|
mapSeries: mapSeries, |
|
mapLimit: mapLimit, |
|
mapValues: mapValues, |
|
mapValuesSeries: mapValuesSeries, |
|
mapValuesLimit: mapValuesLimit, |
|
filter: filter, |
|
filterSeries: filterSeries, |
|
filterLimit: filterLimit, |
|
select: filter, |
|
selectSeries: filterSeries, |
|
selectLimit: filterLimit, |
|
reject: reject, |
|
rejectSeries: rejectSeries, |
|
rejectLimit: rejectLimit, |
|
detect: detect, |
|
detectSeries: detectSeries, |
|
detectLimit: detectLimit, |
|
find: detect, |
|
findSeries: detectSeries, |
|
findLimit: detectLimit, |
|
pick: pick, |
|
pickSeries: pickSeries, |
|
pickLimit: pickLimit, |
|
omit: omit, |
|
omitSeries: omitSeries, |
|
omitLimit: omitLimit, |
|
reduce: reduce, |
|
inject: reduce, |
|
foldl: reduce, |
|
reduceRight: reduceRight, |
|
foldr: reduceRight, |
|
transform: transform, |
|
transformSeries: transformSeries, |
|
transformLimit: transformLimit, |
|
sortBy: sortBy, |
|
sortBySeries: sortBySeries, |
|
sortByLimit: sortByLimit, |
|
some: some, |
|
someSeries: someSeries, |
|
someLimit: someLimit, |
|
any: some, |
|
anySeries: someSeries, |
|
anyLimit: someLimit, |
|
every: every, |
|
everySeries: everySeries, |
|
everyLimit: everyLimit, |
|
all: every, |
|
allSeries: everySeries, |
|
allLimit: everyLimit, |
|
concat: concat, |
|
concatSeries: concatSeries, |
|
concatLimit: concatLimit, |
|
groupBy: groupBy, |
|
groupBySeries: groupBySeries, |
|
groupByLimit: groupByLimit, |
|
|
|
// Control Flow |
|
parallel: parallel, |
|
series: series, |
|
parallelLimit: parallelLimit, |
|
tryEach: tryEach, |
|
waterfall: waterfall, |
|
angelFall: angelFall, |
|
angelfall: angelFall, |
|
whilst: whilst, |
|
doWhilst: doWhilst, |
|
until: until, |
|
doUntil: doUntil, |
|
during: during, |
|
doDuring: doDuring, |
|
forever: forever, |
|
compose: compose, |
|
seq: seq, |
|
applyEach: applyEach, |
|
applyEachSeries: applyEachSeries, |
|
queue: queue, |
|
priorityQueue: priorityQueue, |
|
cargo: cargo, |
|
auto: auto, |
|
autoInject: autoInject, |
|
retry: retry, |
|
retryable: retryable, |
|
iterator: iterator, |
|
times: times, |
|
timesSeries: timesSeries, |
|
timesLimit: timesLimit, |
|
race: race, |
|
|
|
// Utils |
|
apply: apply, |
|
nextTick: asyncNextTick, |
|
setImmediate: asyncSetImmediate, |
|
memoize: memoize, |
|
unmemoize: unmemoize, |
|
ensureAsync: ensureAsync, |
|
constant: constant, |
|
asyncify: asyncify, |
|
wrapSync: asyncify, |
|
log: log, |
|
dir: dir, |
|
reflect: reflect, |
|
reflectAll: reflectAll, |
|
timeout: timeout, |
|
createLogger: createLogger, |
|
|
|
// Mode |
|
safe: safe, |
|
fast: fast |
|
}; |
|
|
|
exports['default'] = index; |
|
baseEachSync( |
|
index, |
|
function(func, key) { |
|
exports[key] = func; |
|
}, |
|
nativeKeys(index) |
|
); |
|
|
|
/** |
|
* @private |
|
*/ |
|
function createImmediate(safeMode) { |
|
var delay = function delay(fn) { |
|
var args = slice(arguments, 1); |
|
setTimeout(function() { |
|
fn.apply(null, args); |
|
}); |
|
}; |
|
asyncSetImmediate = typeof setImmediate === func ? setImmediate : delay; |
|
if (typeof process === obj && typeof process.nextTick === func) { |
|
nextTick = /^v0.10/.test(process.version) ? asyncSetImmediate : process.nextTick; |
|
asyncNextTick = /^v0/.test(process.version) ? asyncSetImmediate : process.nextTick; |
|
} else { |
|
asyncNextTick = nextTick = asyncSetImmediate; |
|
} |
|
if (safeMode === false) { |
|
nextTick = function(cb) { |
|
cb(); |
|
}; |
|
} |
|
} |
|
|
|
/* sync functions based on lodash */ |
|
|
|
/** |
|
* Converts `arguments` to an array. |
|
* |
|
* @private |
|
* @param {Array} array = The array to slice. |
|
*/ |
|
function createArray(array) { |
|
var index = -1; |
|
var size = array.length; |
|
var result = Array(size); |
|
|
|
while (++index < size) { |
|
result[index] = array[index]; |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* Create an array from `start` |
|
* |
|
* @private |
|
* @param {Array} array - The array to slice. |
|
* @param {number} start - The start position. |
|
*/ |
|
function slice(array, start) { |
|
var end = array.length; |
|
var index = -1; |
|
var size = end - start; |
|
if (size <= 0) { |
|
return []; |
|
} |
|
var result = Array(size); |
|
|
|
while (++index < size) { |
|
result[index] = array[index + start]; |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {Object} object |
|
*/ |
|
function objectClone(object) { |
|
var keys = nativeKeys(object); |
|
var size = keys.length; |
|
var index = -1; |
|
var result = {}; |
|
|
|
while (++index < size) { |
|
var key = keys[index]; |
|
result[key] = object[key]; |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* Create an array with all falsey values removed. |
|
* |
|
* @private |
|
* @param {Array} array - The array to compact. |
|
*/ |
|
function compact(array) { |
|
var index = -1; |
|
var size = array.length; |
|
var result = []; |
|
|
|
while (++index < size) { |
|
var value = array[index]; |
|
if (value) { |
|
result[result.length] = value; |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* Create an array of reverse sequence. |
|
* |
|
* @private |
|
* @param {Array} array - The array to reverse. |
|
*/ |
|
function reverse(array) { |
|
var index = -1; |
|
var size = array.length; |
|
var result = Array(size); |
|
var resIndex = size; |
|
|
|
while (++index < size) { |
|
result[--resIndex] = array[index]; |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* Checks if key exists in object property. |
|
* |
|
* @private |
|
* @param {Object} object - The object to inspect. |
|
* @param {string} key - The key to check. |
|
*/ |
|
function has(object, key) { |
|
return object.hasOwnProperty(key); |
|
} |
|
|
|
/** |
|
* Check if target exists in array. |
|
* @private |
|
* @param {Array} array |
|
* @param {*} target |
|
*/ |
|
function notInclude(array, target) { |
|
var index = -1; |
|
var size = array.length; |
|
|
|
while (++index < size) { |
|
if (array[index] === target) { |
|
return false; |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {Array} array - The array to iterate over. |
|
* @param {Function} iterator - The function invoked per iteration. |
|
*/ |
|
function arrayEachSync(array, iterator) { |
|
var index = -1; |
|
var size = array.length; |
|
|
|
while (++index < size) { |
|
iterator(array[index], index); |
|
} |
|
return array; |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {Object} object - The object to iterate over. |
|
* @param {Function} iterator - The function invoked per iteration. |
|
* @param {Array} keys |
|
*/ |
|
function baseEachSync(object, iterator, keys) { |
|
var index = -1; |
|
var size = keys.length; |
|
|
|
while (++index < size) { |
|
var key = keys[index]; |
|
iterator(object[key], key); |
|
} |
|
return object; |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {number} n |
|
* @param {Function} iterator |
|
*/ |
|
function timesSync(n, iterator) { |
|
var index = -1; |
|
while (++index < n) { |
|
iterator(index); |
|
} |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {Array} array |
|
* @param {number[]} criteria |
|
*/ |
|
function sortByCriteria(array, criteria) { |
|
var l = array.length; |
|
var indices = Array(l); |
|
var i; |
|
for (i = 0; i < l; i++) { |
|
indices[i] = i; |
|
} |
|
quickSort(criteria, 0, l - 1, indices); |
|
var result = Array(l); |
|
for (var n = 0; n < l; n++) { |
|
i = indices[n]; |
|
result[n] = i === undefined ? array[n] : array[i]; |
|
} |
|
return result; |
|
} |
|
|
|
function partition(array, i, j, mid, indices) { |
|
var l = i; |
|
var r = j; |
|
while (l <= r) { |
|
i = l; |
|
while (l < r && array[l] < mid) { |
|
l++; |
|
} |
|
while (r >= i && array[r] >= mid) { |
|
r--; |
|
} |
|
if (l > r) { |
|
break; |
|
} |
|
swap(array, indices, l++, r--); |
|
} |
|
return l; |
|
} |
|
|
|
function swap(array, indices, l, r) { |
|
var n = array[l]; |
|
array[l] = array[r]; |
|
array[r] = n; |
|
var i = indices[l]; |
|
indices[l] = indices[r]; |
|
indices[r] = i; |
|
} |
|
|
|
function quickSort(array, i, j, indices) { |
|
if (i === j) { |
|
return; |
|
} |
|
var k = i; |
|
while (++k <= j && array[i] === array[k]) { |
|
var l = k - 1; |
|
if (indices[l] > indices[k]) { |
|
var index = indices[l]; |
|
indices[l] = indices[k]; |
|
indices[k] = index; |
|
} |
|
} |
|
if (k > j) { |
|
return; |
|
} |
|
var p = array[i] > array[k] ? i : k; |
|
k = partition(array, i, j, array[p], indices); |
|
quickSort(array, i, k - 1, indices); |
|
quickSort(array, k, j, indices); |
|
} |
|
|
|
/** |
|
* @Private |
|
*/ |
|
function makeConcatResult(array) { |
|
var result = []; |
|
arrayEachSync(array, function(value) { |
|
if (value === noop) { |
|
return; |
|
} |
|
if (isArray(value)) { |
|
nativePush.apply(result, value); |
|
} else { |
|
result.push(value); |
|
} |
|
}); |
|
return result; |
|
} |
|
|
|
/* async functions */ |
|
|
|
/** |
|
* @private |
|
*/ |
|
function arrayEach(array, iterator, callback) { |
|
var index = -1; |
|
var size = array.length; |
|
|
|
if (iterator.length === 3) { |
|
while (++index < size) { |
|
iterator(array[index], index, onlyOnce(callback)); |
|
} |
|
} else { |
|
while (++index < size) { |
|
iterator(array[index], onlyOnce(callback)); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function baseEach(object, iterator, callback, keys) { |
|
var key; |
|
var index = -1; |
|
var size = keys.length; |
|
|
|
if (iterator.length === 3) { |
|
while (++index < size) { |
|
key = keys[index]; |
|
iterator(object[key], key, onlyOnce(callback)); |
|
} |
|
} else { |
|
while (++index < size) { |
|
iterator(object[keys[index]], onlyOnce(callback)); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function symbolEach(collection, iterator, callback) { |
|
var iter = collection[iteratorSymbol](); |
|
var index = 0; |
|
var item; |
|
if (iterator.length === 3) { |
|
while ((item = iter.next()).done === false) { |
|
iterator(item.value, index++, onlyOnce(callback)); |
|
} |
|
} else { |
|
while ((item = iter.next()).done === false) { |
|
index++; |
|
iterator(item.value, onlyOnce(callback)); |
|
} |
|
} |
|
return index; |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function arrayEachResult(array, result, iterator, callback) { |
|
var index = -1; |
|
var size = array.length; |
|
|
|
if (iterator.length === 4) { |
|
while (++index < size) { |
|
iterator(result, array[index], index, onlyOnce(callback)); |
|
} |
|
} else { |
|
while (++index < size) { |
|
iterator(result, array[index], onlyOnce(callback)); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function baseEachResult(object, result, iterator, callback, keys) { |
|
var key; |
|
var index = -1; |
|
var size = keys.length; |
|
|
|
if (iterator.length === 4) { |
|
while (++index < size) { |
|
key = keys[index]; |
|
iterator(result, object[key], key, onlyOnce(callback)); |
|
} |
|
} else { |
|
while (++index < size) { |
|
iterator(result, object[keys[index]], onlyOnce(callback)); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function symbolEachResult(collection, result, iterator, callback) { |
|
var item; |
|
var index = 0; |
|
var iter = collection[iteratorSymbol](); |
|
|
|
if (iterator.length === 4) { |
|
while ((item = iter.next()).done === false) { |
|
iterator(result, item.value, index++, onlyOnce(callback)); |
|
} |
|
} else { |
|
while ((item = iter.next()).done === false) { |
|
index++; |
|
iterator(result, item.value, onlyOnce(callback)); |
|
} |
|
} |
|
return index; |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function arrayEachFunc(array, createCallback) { |
|
var index = -1; |
|
var size = array.length; |
|
|
|
while (++index < size) { |
|
array[index](createCallback(index)); |
|
} |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function baseEachFunc(object, createCallback, keys) { |
|
var key; |
|
var index = -1; |
|
var size = keys.length; |
|
|
|
while (++index < size) { |
|
key = keys[index]; |
|
object[key](createCallback(key)); |
|
} |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function arrayEachIndex(array, iterator, createCallback) { |
|
var index = -1; |
|
var size = array.length; |
|
|
|
if (iterator.length === 3) { |
|
while (++index < size) { |
|
iterator(array[index], index, createCallback(index)); |
|
} |
|
} else { |
|
while (++index < size) { |
|
iterator(array[index], createCallback(index)); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function baseEachIndex(object, iterator, createCallback, keys) { |
|
var key; |
|
var index = -1; |
|
var size = keys.length; |
|
|
|
if (iterator.length === 3) { |
|
while (++index < size) { |
|
key = keys[index]; |
|
iterator(object[key], key, createCallback(index)); |
|
} |
|
} else { |
|
while (++index < size) { |
|
iterator(object[keys[index]], createCallback(index)); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function symbolEachIndex(collection, iterator, createCallback) { |
|
var item; |
|
var index = 0; |
|
var iter = collection[iteratorSymbol](); |
|
|
|
if (iterator.length === 3) { |
|
while ((item = iter.next()).done === false) { |
|
iterator(item.value, index, createCallback(index++)); |
|
} |
|
} else { |
|
while ((item = iter.next()).done === false) { |
|
iterator(item.value, createCallback(index++)); |
|
} |
|
} |
|
return index; |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function baseEachKey(object, iterator, createCallback, keys) { |
|
var key; |
|
var index = -1; |
|
var size = keys.length; |
|
|
|
if (iterator.length === 3) { |
|
while (++index < size) { |
|
key = keys[index]; |
|
iterator(object[key], key, createCallback(key)); |
|
} |
|
} else { |
|
while (++index < size) { |
|
key = keys[index]; |
|
iterator(object[key], createCallback(key)); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function symbolEachKey(collection, iterator, createCallback) { |
|
var item; |
|
var index = 0; |
|
var iter = collection[iteratorSymbol](); |
|
|
|
if (iterator.length === 3) { |
|
while ((item = iter.next()).done === false) { |
|
iterator(item.value, index, createCallback(index++)); |
|
} |
|
} else { |
|
while ((item = iter.next()).done === false) { |
|
iterator(item.value, createCallback(index++)); |
|
} |
|
} |
|
return index; |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function arrayEachValue(array, iterator, createCallback) { |
|
var value; |
|
var index = -1; |
|
var size = array.length; |
|
|
|
if (iterator.length === 3) { |
|
while (++index < size) { |
|
value = array[index]; |
|
iterator(value, index, createCallback(value)); |
|
} |
|
} else { |
|
while (++index < size) { |
|
value = array[index]; |
|
iterator(value, createCallback(value)); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function baseEachValue(object, iterator, createCallback, keys) { |
|
var key, value; |
|
var index = -1; |
|
var size = keys.length; |
|
|
|
if (iterator.length === 3) { |
|
while (++index < size) { |
|
key = keys[index]; |
|
value = object[key]; |
|
iterator(value, key, createCallback(value)); |
|
} |
|
} else { |
|
while (++index < size) { |
|
value = object[keys[index]]; |
|
iterator(value, createCallback(value)); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function symbolEachValue(collection, iterator, createCallback) { |
|
var value, item; |
|
var index = 0; |
|
var iter = collection[iteratorSymbol](); |
|
|
|
if (iterator.length === 3) { |
|
while ((item = iter.next()).done === false) { |
|
value = item.value; |
|
iterator(value, index++, createCallback(value)); |
|
} |
|
} else { |
|
while ((item = iter.next()).done === false) { |
|
index++; |
|
value = item.value; |
|
iterator(value, createCallback(value)); |
|
} |
|
} |
|
return index; |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function arrayEachIndexValue(array, iterator, createCallback) { |
|
var value; |
|
var index = -1; |
|
var size = array.length; |
|
|
|
if (iterator.length === 3) { |
|
while (++index < size) { |
|
value = array[index]; |
|
iterator(value, index, createCallback(index, value)); |
|
} |
|
} else { |
|
while (++index < size) { |
|
value = array[index]; |
|
iterator(value, createCallback(index, value)); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function baseEachIndexValue(object, iterator, createCallback, keys) { |
|
var key, value; |
|
var index = -1; |
|
var size = keys.length; |
|
|
|
if (iterator.length === 3) { |
|
while (++index < size) { |
|
key = keys[index]; |
|
value = object[key]; |
|
iterator(value, key, createCallback(index, value)); |
|
} |
|
} else { |
|
while (++index < size) { |
|
value = object[keys[index]]; |
|
iterator(value, createCallback(index, value)); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function symbolEachIndexValue(collection, iterator, createCallback) { |
|
var value, item; |
|
var index = 0; |
|
var iter = collection[iteratorSymbol](); |
|
|
|
if (iterator.length === 3) { |
|
while ((item = iter.next()).done === false) { |
|
value = item.value; |
|
iterator(value, index, createCallback(index++, value)); |
|
} |
|
} else { |
|
while ((item = iter.next()).done === false) { |
|
value = item.value; |
|
iterator(value, createCallback(index++, value)); |
|
} |
|
} |
|
return index; |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function baseEachKeyValue(object, iterator, createCallback, keys) { |
|
var key, value; |
|
var index = -1; |
|
var size = keys.length; |
|
|
|
if (iterator.length === 3) { |
|
while (++index < size) { |
|
key = keys[index]; |
|
value = object[key]; |
|
iterator(value, key, createCallback(key, value)); |
|
} |
|
} else { |
|
while (++index < size) { |
|
key = keys[index]; |
|
value = object[key]; |
|
iterator(value, createCallback(key, value)); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function symbolEachKeyValue(collection, iterator, createCallback) { |
|
var value, item; |
|
var index = 0; |
|
var iter = collection[iteratorSymbol](); |
|
|
|
if (iterator.length === 3) { |
|
while ((item = iter.next()).done === false) { |
|
value = item.value; |
|
iterator(value, index, createCallback(index++, value)); |
|
} |
|
} else { |
|
while ((item = iter.next()).done === false) { |
|
value = item.value; |
|
iterator(value, createCallback(index++, value)); |
|
} |
|
} |
|
return index; |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {Function} func |
|
*/ |
|
function onlyOnce(func) { |
|
return function(err, res) { |
|
var fn = func; |
|
func = throwError; |
|
fn(err, res); |
|
}; |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {Function} func |
|
*/ |
|
function once(func) { |
|
return function(err, res) { |
|
var fn = func; |
|
func = noop; |
|
fn(err, res); |
|
}; |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {Function} arrayEach |
|
* @param {Function} baseEach |
|
*/ |
|
function createEach(arrayEach, baseEach, symbolEach) { |
|
return function each(collection, iterator, callback) { |
|
callback = once(callback || noop); |
|
var size, keys; |
|
var completed = 0; |
|
if (isArray(collection)) { |
|
size = collection.length; |
|
arrayEach(collection, iterator, done); |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = symbolEach(collection, iterator, done); |
|
size && size === completed && callback(null); |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
baseEach(collection, iterator, done, keys); |
|
} |
|
if (!size) { |
|
callback(null); |
|
} |
|
|
|
function done(err, bool) { |
|
if (err) { |
|
callback = once(callback); |
|
callback(err); |
|
} else if (++completed === size) { |
|
callback(null); |
|
} else if (bool === false) { |
|
callback = once(callback); |
|
callback(null); |
|
} |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {Function} arrayEach |
|
* @param {Function} baseEach |
|
* @param {Function} symbolEach |
|
*/ |
|
function createMap(arrayEach, baseEach, symbolEach, useArray) { |
|
var init, clone; |
|
if (useArray) { |
|
init = Array; |
|
clone = createArray; |
|
} else { |
|
init = function() { |
|
return {}; |
|
}; |
|
clone = objectClone; |
|
} |
|
|
|
return function(collection, iterator, callback) { |
|
callback = callback || noop; |
|
var size, keys, result; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
result = init(size); |
|
arrayEach(collection, iterator, createCallback); |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
// TODO: size could be changed |
|
result = init(0); |
|
size = symbolEach(collection, iterator, createCallback); |
|
size && size === completed && callback(null, result); |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
result = init(size); |
|
baseEach(collection, iterator, createCallback, keys); |
|
} |
|
if (!size) { |
|
callback(null, init()); |
|
} |
|
|
|
function createCallback(key) { |
|
return function done(err, res) { |
|
if (key === null) { |
|
throwError(); |
|
} |
|
if (err) { |
|
key = null; |
|
callback = once(callback); |
|
callback(err, clone(result)); |
|
return; |
|
} |
|
result[key] = res; |
|
key = null; |
|
if (++completed === size) { |
|
callback(null, result); |
|
} |
|
}; |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {Function} arrayEach |
|
* @param {Function} baseEach |
|
* @param {Function} symbolEach |
|
* @param {boolean} bool |
|
*/ |
|
function createFilter(arrayEach, baseEach, symbolEach, bool) { |
|
return function(collection, iterator, callback) { |
|
callback = callback || noop; |
|
var size, keys, result; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
result = Array(size); |
|
arrayEach(collection, iterator, createCallback); |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
result = []; |
|
size = symbolEach(collection, iterator, createCallback); |
|
size && size === completed && callback(null, compact(result)); |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
result = Array(size); |
|
baseEach(collection, iterator, createCallback, keys); |
|
} |
|
if (!size) { |
|
return callback(null, []); |
|
} |
|
|
|
function createCallback(index, value) { |
|
return function done(err, res) { |
|
if (index === null) { |
|
throwError(); |
|
} |
|
if (err) { |
|
index = null; |
|
callback = once(callback); |
|
callback(err); |
|
return; |
|
} |
|
if (!!res === bool) { |
|
result[index] = value; |
|
} |
|
index = null; |
|
if (++completed === size) { |
|
callback(null, compact(result)); |
|
} |
|
}; |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {boolean} bool |
|
*/ |
|
function createFilterSeries(bool) { |
|
return function(collection, iterator, callback) { |
|
callback = onlyOnce(callback || noop); |
|
var size, key, value, keys, iter, item, iterate; |
|
var sync = false; |
|
var completed = 0; |
|
var result = []; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = Infinity; |
|
iter = collection[iteratorSymbol](); |
|
iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; |
|
} |
|
if (!size) { |
|
return callback(null, []); |
|
} |
|
iterate(); |
|
|
|
function arrayIterator() { |
|
value = collection[completed]; |
|
iterator(value, done); |
|
} |
|
|
|
function arrayIteratorWithIndex() { |
|
value = collection[completed]; |
|
iterator(value, completed, done); |
|
} |
|
|
|
function symbolIterator() { |
|
item = iter.next(); |
|
value = item.value; |
|
item.done ? callback(null, result) : iterator(value, done); |
|
} |
|
|
|
function symbolIteratorWithKey() { |
|
item = iter.next(); |
|
value = item.value; |
|
item.done ? callback(null, result) : iterator(value, completed, done); |
|
} |
|
|
|
function objectIterator() { |
|
key = keys[completed]; |
|
value = collection[key]; |
|
iterator(value, done); |
|
} |
|
|
|
function objectIteratorWithKey() { |
|
key = keys[completed]; |
|
value = collection[key]; |
|
iterator(value, key, done); |
|
} |
|
|
|
function done(err, res) { |
|
if (err) { |
|
callback(err); |
|
return; |
|
} |
|
if (!!res === bool) { |
|
result[result.length] = value; |
|
} |
|
if (++completed === size) { |
|
iterate = throwError; |
|
callback(null, result); |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {boolean} bool |
|
*/ |
|
function createFilterLimit(bool) { |
|
return function(collection, limit, iterator, callback) { |
|
callback = callback || noop; |
|
var size, index, key, value, keys, iter, item, iterate, result; |
|
var sync = false; |
|
var started = 0; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = Infinity; |
|
result = []; |
|
iter = collection[iteratorSymbol](); |
|
iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; |
|
} |
|
if (!size || isNaN(limit) || limit < 1) { |
|
return callback(null, []); |
|
} |
|
result = result || Array(size); |
|
timesSync(limit > size ? size : limit, iterate); |
|
|
|
function arrayIterator() { |
|
index = started++; |
|
if (index < size) { |
|
value = collection[index]; |
|
iterator(value, createCallback(value, index)); |
|
} |
|
} |
|
|
|
function arrayIteratorWithIndex() { |
|
index = started++; |
|
if (index < size) { |
|
value = collection[index]; |
|
iterator(value, index, createCallback(value, index)); |
|
} |
|
} |
|
|
|
function symbolIterator() { |
|
item = iter.next(); |
|
if (item.done === false) { |
|
value = item.value; |
|
iterator(value, createCallback(value, started++)); |
|
} else if (completed === started && iterator !== noop) { |
|
iterator = noop; |
|
callback(null, compact(result)); |
|
} |
|
} |
|
|
|
function symbolIteratorWithKey() { |
|
item = iter.next(); |
|
if (item.done === false) { |
|
value = item.value; |
|
iterator(value, started, createCallback(value, started++)); |
|
} else if (completed === started && iterator !== noop) { |
|
iterator = noop; |
|
callback(null, compact(result)); |
|
} |
|
} |
|
|
|
function objectIterator() { |
|
index = started++; |
|
if (index < size) { |
|
value = collection[keys[index]]; |
|
iterator(value, createCallback(value, index)); |
|
} |
|
} |
|
|
|
function objectIteratorWithKey() { |
|
index = started++; |
|
if (index < size) { |
|
key = keys[index]; |
|
value = collection[key]; |
|
iterator(value, key, createCallback(value, index)); |
|
} |
|
} |
|
|
|
function createCallback(value, index) { |
|
return function(err, res) { |
|
if (index === null) { |
|
throwError(); |
|
} |
|
if (err) { |
|
index = null; |
|
iterate = noop; |
|
callback = once(callback); |
|
callback(err); |
|
return; |
|
} |
|
if (!!res === bool) { |
|
result[index] = value; |
|
} |
|
index = null; |
|
if (++completed === size) { |
|
callback = onlyOnce(callback); |
|
callback(null, compact(result)); |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
}; |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace eachSeries |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.eachSeries(array, iterator, function(err, res) { |
|
* console.log(res); // undefined |
|
* console.log(order); // [1, 3, 2] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.eachSeries(array, iterator, function(err, res) { |
|
* console.log(res); // undefined |
|
* console.log(order); // [[1, 0], [3, 1], [2, 2]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.eachSeries(object, iterator, function(err, res) { |
|
* console.log(res); // undefined |
|
* console.log(order); // [1, 3, 2] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.eachSeries(object, iterator, function(err, res) { |
|
* console.log(res); // undefined |
|
* console.log(order); // [[1, 'a'], [3, 'b'], [2, 'b']] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // break |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num !== 3); |
|
* }, num * 10); |
|
* }; |
|
* async.eachSeries(array, iterator, function(err, res) { |
|
* console.log(res); // undefined |
|
* console.log(order); // [1, 3] |
|
* }); |
|
*/ |
|
function eachSeries(collection, iterator, callback) { |
|
callback = onlyOnce(callback || noop); |
|
var size, key, keys, iter, item, iterate; |
|
var sync = false; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = Infinity; |
|
iter = collection[iteratorSymbol](); |
|
iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; |
|
} |
|
if (!size) { |
|
return callback(null); |
|
} |
|
iterate(); |
|
|
|
function arrayIterator() { |
|
iterator(collection[completed], done); |
|
} |
|
|
|
function arrayIteratorWithIndex() { |
|
iterator(collection[completed], completed, done); |
|
} |
|
|
|
function symbolIterator() { |
|
item = iter.next(); |
|
item.done ? callback(null) : iterator(item.value, done); |
|
} |
|
|
|
function symbolIteratorWithKey() { |
|
item = iter.next(); |
|
item.done ? callback(null) : iterator(item.value, completed, done); |
|
} |
|
|
|
function objectIterator() { |
|
iterator(collection[keys[completed]], done); |
|
} |
|
|
|
function objectIteratorWithKey() { |
|
key = keys[completed]; |
|
iterator(collection[key], key, done); |
|
} |
|
|
|
function done(err, bool) { |
|
if (err) { |
|
callback(err); |
|
} else if (++completed === size || bool === false) { |
|
iterate = throwError; |
|
callback(null); |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace eachLimit |
|
* @param {Array|Object} collection |
|
* @param {number} limit - limit >= 1 |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.eachLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // undefined |
|
* console.log(order); // [1, 3, 5, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.eachLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // undefined |
|
* console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.eachLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // undefined |
|
* console.log(order); // [1, 3, 5, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.eachLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // undefined |
|
* console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // break |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num !== 5); |
|
* }, num * 10); |
|
* }; |
|
* async.eachLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // undefined |
|
* console.log(order); // [1, 3, 5] |
|
* }); |
|
* |
|
*/ |
|
function eachLimit(collection, limit, iterator, callback) { |
|
callback = callback || noop; |
|
var size, index, key, keys, iter, item, iterate; |
|
var sync = false; |
|
var started = 0; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = Infinity; |
|
iter = collection[iteratorSymbol](); |
|
iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; |
|
} else { |
|
return callback(null); |
|
} |
|
if (!size || isNaN(limit) || limit < 1) { |
|
return callback(null); |
|
} |
|
timesSync(limit > size ? size : limit, iterate); |
|
|
|
function arrayIterator() { |
|
if (started < size) { |
|
iterator(collection[started++], done); |
|
} |
|
} |
|
|
|
function arrayIteratorWithIndex() { |
|
index = started++; |
|
if (index < size) { |
|
iterator(collection[index], index, done); |
|
} |
|
} |
|
|
|
function symbolIterator() { |
|
item = iter.next(); |
|
if (item.done === false) { |
|
started++; |
|
iterator(item.value, done); |
|
} else if (completed === started && iterator !== noop) { |
|
iterator = noop; |
|
callback(null); |
|
} |
|
} |
|
|
|
function symbolIteratorWithKey() { |
|
item = iter.next(); |
|
if (item.done === false) { |
|
iterator(item.value, started++, done); |
|
} else if (completed === started && iterator !== noop) { |
|
iterator = noop; |
|
callback(null); |
|
} |
|
} |
|
|
|
function objectIterator() { |
|
if (started < size) { |
|
iterator(collection[keys[started++]], done); |
|
} |
|
} |
|
|
|
function objectIteratorWithKey() { |
|
index = started++; |
|
if (index < size) { |
|
key = keys[index]; |
|
iterator(collection[key], key, done); |
|
} |
|
} |
|
|
|
function done(err, bool) { |
|
if (err || bool === false) { |
|
iterate = noop; |
|
callback = once(callback); |
|
callback(err); |
|
} else if (++completed === size) { |
|
iterator = noop; |
|
iterate = throwError; |
|
callback = onlyOnce(callback); |
|
callback(null); |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace mapSeries |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.mapSeries(array, iterator, function(err, res) { |
|
* console.log(res); // [1, 3, 2]; |
|
* console.log(order); // [1, 3, 2] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.mapSeries(array, iterator, function(err, res) { |
|
* console.log(res); // [1, 3, 2] |
|
* console.log(order); // [[1, 0], [3, 1], [2, 2]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.mapSeries(object, iterator, function(err, res) { |
|
* console.log(res); // [1, 3, 2] |
|
* console.log(order); // [1, 3, 2] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.mapSeries(object, iterator, function(err, res) { |
|
* console.log(res); // [1, 3, 2] |
|
* console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']] |
|
* }); |
|
* |
|
*/ |
|
function mapSeries(collection, iterator, callback) { |
|
callback = callback || noop; |
|
var size, key, keys, iter, item, result, iterate; |
|
var sync = false; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = Infinity; |
|
result = []; |
|
iter = collection[iteratorSymbol](); |
|
iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; |
|
} |
|
if (!size) { |
|
return callback(null, []); |
|
} |
|
result = result || Array(size); |
|
iterate(); |
|
|
|
function arrayIterator() { |
|
iterator(collection[completed], done); |
|
} |
|
|
|
function arrayIteratorWithIndex() { |
|
iterator(collection[completed], completed, done); |
|
} |
|
|
|
function symbolIterator() { |
|
item = iter.next(); |
|
item.done ? callback(null, result) : iterator(item.value, done); |
|
} |
|
|
|
function symbolIteratorWithKey() { |
|
item = iter.next(); |
|
item.done ? callback(null, result) : iterator(item.value, completed, done); |
|
} |
|
|
|
function objectIterator() { |
|
iterator(collection[keys[completed]], done); |
|
} |
|
|
|
function objectIteratorWithKey() { |
|
key = keys[completed]; |
|
iterator(collection[key], key, done); |
|
} |
|
|
|
function done(err, res) { |
|
if (err) { |
|
iterate = throwError; |
|
callback = onlyOnce(callback); |
|
callback(err, createArray(result)); |
|
return; |
|
} |
|
result[completed] = res; |
|
if (++completed === size) { |
|
iterate = throwError; |
|
callback(null, result); |
|
callback = throwError; |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace mapLimit |
|
* @param {Array|Object} collection |
|
* @param {number} limit - limit >= 1 |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.mapLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // [1, 5, 3, 4, 2] |
|
* console.log(order); // [1, 3, 5, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.mapLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // [1, 5, 3, 4, 2] |
|
* console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.mapLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // [1, 5, 3, 4, 2] |
|
* console.log(order); // [1, 3, 5, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.mapLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // [1, 5, 3, 4, 2] |
|
* console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']] |
|
* }); |
|
* |
|
*/ |
|
function mapLimit(collection, limit, iterator, callback) { |
|
callback = callback || noop; |
|
var size, index, key, keys, iter, item, result, iterate; |
|
var sync = false; |
|
var started = 0; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = Infinity; |
|
result = []; |
|
iter = collection[iteratorSymbol](); |
|
iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; |
|
} |
|
if (!size || isNaN(limit) || limit < 1) { |
|
return callback(null, []); |
|
} |
|
result = result || Array(size); |
|
timesSync(limit > size ? size : limit, iterate); |
|
|
|
function arrayIterator() { |
|
index = started++; |
|
if (index < size) { |
|
iterator(collection[index], createCallback(index)); |
|
} |
|
} |
|
|
|
function arrayIteratorWithIndex() { |
|
index = started++; |
|
if (index < size) { |
|
iterator(collection[index], index, createCallback(index)); |
|
} |
|
} |
|
|
|
function symbolIterator() { |
|
item = iter.next(); |
|
if (item.done === false) { |
|
iterator(item.value, createCallback(started++)); |
|
} else if (completed === started && iterator !== noop) { |
|
iterator = noop; |
|
callback(null, result); |
|
} |
|
} |
|
|
|
function symbolIteratorWithKey() { |
|
item = iter.next(); |
|
if (item.done === false) { |
|
iterator(item.value, started, createCallback(started++)); |
|
} else if (completed === started && iterator !== noop) { |
|
iterator = noop; |
|
callback(null, result); |
|
} |
|
} |
|
|
|
function objectIterator() { |
|
index = started++; |
|
if (index < size) { |
|
iterator(collection[keys[index]], createCallback(index)); |
|
} |
|
} |
|
|
|
function objectIteratorWithKey() { |
|
index = started++; |
|
if (index < size) { |
|
key = keys[index]; |
|
iterator(collection[key], key, createCallback(index)); |
|
} |
|
} |
|
|
|
function createCallback(index) { |
|
return function(err, res) { |
|
if (index === null) { |
|
throwError(); |
|
} |
|
if (err) { |
|
index = null; |
|
iterate = noop; |
|
callback = once(callback); |
|
callback(err, createArray(result)); |
|
return; |
|
} |
|
result[index] = res; |
|
index = null; |
|
if (++completed === size) { |
|
iterate = throwError; |
|
callback(null, result); |
|
callback = throwError; |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
}; |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace mapValuesSeries |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.mapValuesSeries(array, iterator, function(err, res) { |
|
* console.log(res); // { '0': 1, '1': 3, '2': 2 } |
|
* console.log(order); // [1, 3, 2] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.mapValuesSeries(array, iterator, function(err, res) { |
|
* console.log(res); // { '0': 1, '1': 3, '2': 2 } |
|
* console.log(order); // [[1, 0], [3, 1], [2, 2]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.mapValuesSeries(object, iterator, function(err, res) { |
|
* console.log(res); // { a: 1, b: 3, c: 2 } |
|
* console.log(order); // [1, 3, 2] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.mapValuesSeries(object, iterator, function(err, res) { |
|
* console.log(res); // { a: 1, b: 3, c: 2 } |
|
* console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']] |
|
* }); |
|
* |
|
*/ |
|
function mapValuesSeries(collection, iterator, callback) { |
|
callback = callback || noop; |
|
var size, key, keys, iter, item, iterate; |
|
var sync = false; |
|
var result = {}; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = Infinity; |
|
iter = collection[iteratorSymbol](); |
|
iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; |
|
} |
|
if (!size) { |
|
return callback(null, result); |
|
} |
|
iterate(); |
|
|
|
function arrayIterator() { |
|
key = completed; |
|
iterator(collection[completed], done); |
|
} |
|
|
|
function arrayIteratorWithIndex() { |
|
key = completed; |
|
iterator(collection[completed], completed, done); |
|
} |
|
|
|
function symbolIterator() { |
|
key = completed; |
|
item = iter.next(); |
|
item.done ? callback(null, result) : iterator(item.value, done); |
|
} |
|
|
|
function symbolIteratorWithKey() { |
|
key = completed; |
|
item = iter.next(); |
|
item.done ? callback(null, result) : iterator(item.value, completed, done); |
|
} |
|
|
|
function objectIterator() { |
|
key = keys[completed]; |
|
iterator(collection[key], done); |
|
} |
|
|
|
function objectIteratorWithKey() { |
|
key = keys[completed]; |
|
iterator(collection[key], key, done); |
|
} |
|
|
|
function done(err, res) { |
|
if (err) { |
|
iterate = throwError; |
|
callback = onlyOnce(callback); |
|
callback(err, objectClone(result)); |
|
return; |
|
} |
|
result[key] = res; |
|
if (++completed === size) { |
|
iterate = throwError; |
|
callback(null, result); |
|
callback = throwError; |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace mapValuesLimit |
|
* @param {Array|Object} collection |
|
* @param {number} limit - limit >= 1 |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.mapValuesLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // { '0': 1, '1': 5, '2': 3, '3': 4, '4': 2 } |
|
* console.log(order); // [1, 3, 5, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.mapValuesLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // { '0': 1, '1': 5, '2': 3, '3': 4, '4': 2 } |
|
* console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.mapValuesLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // { a: 1, b: 5, c: 3, d: 4, e: 2 } |
|
* console.log(order); // [1, 3, 5, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.mapValuesLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // { a: 1, b: 5, c: 3, d: 4, e: 2 } |
|
* console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']] |
|
* }); |
|
* |
|
*/ |
|
function mapValuesLimit(collection, limit, iterator, callback) { |
|
callback = callback || noop; |
|
var size, index, key, keys, iter, item, iterate; |
|
var sync = false; |
|
var result = {}; |
|
var started = 0; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = Infinity; |
|
iter = collection[iteratorSymbol](); |
|
iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; |
|
} |
|
if (!size || isNaN(limit) || limit < 1) { |
|
return callback(null, result); |
|
} |
|
timesSync(limit > size ? size : limit, iterate); |
|
|
|
function arrayIterator() { |
|
index = started++; |
|
if (index < size) { |
|
iterator(collection[index], createCallback(index)); |
|
} |
|
} |
|
|
|
function arrayIteratorWithIndex() { |
|
index = started++; |
|
if (index < size) { |
|
iterator(collection[index], index, createCallback(index)); |
|
} |
|
} |
|
|
|
function symbolIterator() { |
|
item = iter.next(); |
|
if (item.done === false) { |
|
iterator(item.value, createCallback(started++)); |
|
} else if (completed === started && iterator !== noop) { |
|
iterator = noop; |
|
callback(null, result); |
|
} |
|
} |
|
|
|
function symbolIteratorWithKey() { |
|
item = iter.next(); |
|
if (item.done === false) { |
|
iterator(item.value, started, createCallback(started++)); |
|
} else if (completed === started && iterator !== noop) { |
|
iterator = noop; |
|
callback(null, result); |
|
} |
|
} |
|
|
|
function objectIterator() { |
|
index = started++; |
|
if (index < size) { |
|
key = keys[index]; |
|
iterator(collection[key], createCallback(key)); |
|
} |
|
} |
|
|
|
function objectIteratorWithKey() { |
|
index = started++; |
|
if (index < size) { |
|
key = keys[index]; |
|
iterator(collection[key], key, createCallback(key)); |
|
} |
|
} |
|
|
|
function createCallback(key) { |
|
return function(err, res) { |
|
if (key === null) { |
|
throwError(); |
|
} |
|
if (err) { |
|
key = null; |
|
iterate = noop; |
|
callback = once(callback); |
|
callback(err, objectClone(result)); |
|
return; |
|
} |
|
result[key] = res; |
|
key = null; |
|
if (++completed === size) { |
|
callback(null, result); |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
}; |
|
} |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {Function} arrayEach |
|
* @param {Function} baseEach |
|
* @param {Function} symbolEach |
|
* @param {boolean} bool |
|
*/ |
|
function createDetect(arrayEach, baseEach, symbolEach, bool) { |
|
return function(collection, iterator, callback) { |
|
callback = callback || noop; |
|
var size, keys; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
arrayEach(collection, iterator, createCallback); |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = symbolEach(collection, iterator, createCallback); |
|
size && size === completed && callback(null); |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
baseEach(collection, iterator, createCallback, keys); |
|
} |
|
if (!size) { |
|
callback(null); |
|
} |
|
|
|
function createCallback(value) { |
|
var called = false; |
|
return function done(err, res) { |
|
if (called) { |
|
throwError(); |
|
} |
|
called = true; |
|
if (err) { |
|
callback = once(callback); |
|
callback(err); |
|
} else if (!!res === bool) { |
|
callback = once(callback); |
|
callback(null, value); |
|
} else if (++completed === size) { |
|
callback(null); |
|
} |
|
}; |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {boolean} bool |
|
*/ |
|
function createDetectSeries(bool) { |
|
return function(collection, iterator, callback) { |
|
callback = onlyOnce(callback || noop); |
|
var size, key, value, keys, iter, item, iterate; |
|
var sync = false; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = Infinity; |
|
iter = collection[iteratorSymbol](); |
|
iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; |
|
} |
|
if (!size) { |
|
return callback(null); |
|
} |
|
iterate(); |
|
|
|
function arrayIterator() { |
|
value = collection[completed]; |
|
iterator(value, done); |
|
} |
|
|
|
function arrayIteratorWithIndex() { |
|
value = collection[completed]; |
|
iterator(value, completed, done); |
|
} |
|
|
|
function symbolIterator() { |
|
item = iter.next(); |
|
value = item.value; |
|
item.done ? callback(null) : iterator(value, done); |
|
} |
|
|
|
function symbolIteratorWithKey() { |
|
item = iter.next(); |
|
value = item.value; |
|
item.done ? callback(null) : iterator(value, completed, done); |
|
} |
|
|
|
function objectIterator() { |
|
value = collection[keys[completed]]; |
|
iterator(value, done); |
|
} |
|
|
|
function objectIteratorWithKey() { |
|
key = keys[completed]; |
|
value = collection[key]; |
|
iterator(value, key, done); |
|
} |
|
|
|
function done(err, res) { |
|
if (err) { |
|
callback(err); |
|
} else if (!!res === bool) { |
|
iterate = throwError; |
|
callback(null, value); |
|
} else if (++completed === size) { |
|
iterate = throwError; |
|
callback(null); |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {boolean} bool |
|
*/ |
|
function createDetectLimit(bool) { |
|
return function(collection, limit, iterator, callback) { |
|
callback = callback || noop; |
|
var size, index, key, value, keys, iter, item, iterate; |
|
var sync = false; |
|
var started = 0; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = Infinity; |
|
iter = collection[iteratorSymbol](); |
|
iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; |
|
} |
|
if (!size || isNaN(limit) || limit < 1) { |
|
return callback(null); |
|
} |
|
timesSync(limit > size ? size : limit, iterate); |
|
|
|
function arrayIterator() { |
|
index = started++; |
|
if (index < size) { |
|
value = collection[index]; |
|
iterator(value, createCallback(value)); |
|
} |
|
} |
|
|
|
function arrayIteratorWithIndex() { |
|
index = started++; |
|
if (index < size) { |
|
value = collection[index]; |
|
iterator(value, index, createCallback(value)); |
|
} |
|
} |
|
|
|
function symbolIterator() { |
|
item = iter.next(); |
|
if (item.done === false) { |
|
started++; |
|
value = item.value; |
|
iterator(value, createCallback(value)); |
|
} else if (completed === started && iterator !== noop) { |
|
iterator = noop; |
|
callback(null); |
|
} |
|
} |
|
|
|
function symbolIteratorWithKey() { |
|
item = iter.next(); |
|
if (item.done === false) { |
|
value = item.value; |
|
iterator(value, started++, createCallback(value)); |
|
} else if (completed === started && iterator !== noop) { |
|
iterator = noop; |
|
callback(null); |
|
} |
|
} |
|
|
|
function objectIterator() { |
|
index = started++; |
|
if (index < size) { |
|
value = collection[keys[index]]; |
|
iterator(value, createCallback(value)); |
|
} |
|
} |
|
|
|
function objectIteratorWithKey() { |
|
if (started < size) { |
|
key = keys[started++]; |
|
value = collection[key]; |
|
iterator(value, key, createCallback(value)); |
|
} |
|
} |
|
|
|
function createCallback(value) { |
|
var called = false; |
|
return function(err, res) { |
|
if (called) { |
|
throwError(); |
|
} |
|
called = true; |
|
if (err) { |
|
iterate = noop; |
|
callback = once(callback); |
|
callback(err); |
|
} else if (!!res === bool) { |
|
iterate = noop; |
|
callback = once(callback); |
|
callback(null, value); |
|
} else if (++completed === size) { |
|
callback(null); |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
}; |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {Function} arrayEach |
|
* @param {Function} baseEach |
|
* @param {Function} symbolEach |
|
* @param {boolean} bool |
|
*/ |
|
function createPick(arrayEach, baseEach, symbolEach, bool) { |
|
return function(collection, iterator, callback) { |
|
callback = callback || noop; |
|
var size, keys; |
|
var completed = 0; |
|
var result = {}; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
arrayEach(collection, iterator, createCallback); |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = symbolEach(collection, iterator, createCallback); |
|
size && size === completed && callback(null, result); |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
baseEach(collection, iterator, createCallback, keys); |
|
} |
|
if (!size) { |
|
return callback(null, {}); |
|
} |
|
|
|
function createCallback(key, value) { |
|
return function done(err, res) { |
|
if (key === null) { |
|
throwError(); |
|
} |
|
if (err) { |
|
key = null; |
|
callback = once(callback); |
|
callback(err, objectClone(result)); |
|
return; |
|
} |
|
if (!!res === bool) { |
|
result[key] = value; |
|
} |
|
key = null; |
|
if (++completed === size) { |
|
callback(null, result); |
|
} |
|
}; |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {boolean} bool |
|
*/ |
|
function createPickSeries(bool) { |
|
return function(collection, iterator, callback) { |
|
callback = onlyOnce(callback || noop); |
|
var size, key, value, keys, iter, item, iterate; |
|
var sync = false; |
|
var result = {}; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = Infinity; |
|
iter = collection[iteratorSymbol](); |
|
iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; |
|
} |
|
if (!size) { |
|
return callback(null, {}); |
|
} |
|
iterate(); |
|
|
|
function arrayIterator() { |
|
key = completed; |
|
value = collection[completed]; |
|
iterator(value, done); |
|
} |
|
|
|
function arrayIteratorWithIndex() { |
|
key = completed; |
|
value = collection[completed]; |
|
iterator(value, completed, done); |
|
} |
|
|
|
function symbolIterator() { |
|
key = completed; |
|
item = iter.next(); |
|
value = item.value; |
|
item.done ? callback(null, result) : iterator(value, done); |
|
} |
|
|
|
function symbolIteratorWithKey() { |
|
key = completed; |
|
item = iter.next(); |
|
value = item.value; |
|
item.done ? callback(null, result) : iterator(value, key, done); |
|
} |
|
|
|
function objectIterator() { |
|
key = keys[completed]; |
|
value = collection[key]; |
|
iterator(value, done); |
|
} |
|
|
|
function objectIteratorWithKey() { |
|
key = keys[completed]; |
|
value = collection[key]; |
|
iterator(value, key, done); |
|
} |
|
|
|
function done(err, res) { |
|
if (err) { |
|
callback(err, result); |
|
return; |
|
} |
|
if (!!res === bool) { |
|
result[key] = value; |
|
} |
|
if (++completed === size) { |
|
iterate = throwError; |
|
callback(null, result); |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {boolean} bool |
|
*/ |
|
function createPickLimit(bool) { |
|
return function(collection, limit, iterator, callback) { |
|
callback = callback || noop; |
|
var size, index, key, value, keys, iter, item, iterate; |
|
var sync = false; |
|
var result = {}; |
|
var started = 0; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = Infinity; |
|
iter = collection[iteratorSymbol](); |
|
iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; |
|
} |
|
if (!size || isNaN(limit) || limit < 1) { |
|
return callback(null, {}); |
|
} |
|
timesSync(limit > size ? size : limit, iterate); |
|
|
|
function arrayIterator() { |
|
index = started++; |
|
if (index < size) { |
|
value = collection[index]; |
|
iterator(value, createCallback(value, index)); |
|
} |
|
} |
|
|
|
function arrayIteratorWithIndex() { |
|
index = started++; |
|
if (index < size) { |
|
value = collection[index]; |
|
iterator(value, index, createCallback(value, index)); |
|
} |
|
} |
|
|
|
function symbolIterator() { |
|
item = iter.next(); |
|
if (item.done === false) { |
|
value = item.value; |
|
iterator(value, createCallback(value, started++)); |
|
} else if (completed === started && iterator !== noop) { |
|
iterator = noop; |
|
callback(null, result); |
|
} |
|
} |
|
|
|
function symbolIteratorWithKey() { |
|
item = iter.next(); |
|
if (item.done === false) { |
|
value = item.value; |
|
iterator(value, started, createCallback(value, started++)); |
|
} else if (completed === started && iterator !== noop) { |
|
iterator = noop; |
|
callback(null, result); |
|
} |
|
} |
|
|
|
function objectIterator() { |
|
if (started < size) { |
|
key = keys[started++]; |
|
value = collection[key]; |
|
iterator(value, createCallback(value, key)); |
|
} |
|
} |
|
|
|
function objectIteratorWithKey() { |
|
if (started < size) { |
|
key = keys[started++]; |
|
value = collection[key]; |
|
iterator(value, key, createCallback(value, key)); |
|
} |
|
} |
|
|
|
function createCallback(value, key) { |
|
return function(err, res) { |
|
if (key === null) { |
|
throwError(); |
|
} |
|
if (err) { |
|
key = null; |
|
iterate = noop; |
|
callback = once(callback); |
|
callback(err, objectClone(result)); |
|
return; |
|
} |
|
if (!!res === bool) { |
|
result[key] = value; |
|
} |
|
key = null; |
|
if (++completed === size) { |
|
iterate = throwError; |
|
callback = onlyOnce(callback); |
|
callback(null, result); |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
}; |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace reduce |
|
* @param {Array|Object} collection |
|
* @param {*} result |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var collection = [1, 3, 2, 4]; |
|
* var iterator = function(result, num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, result + num); |
|
* }, num * 10); |
|
* }; |
|
* async.reduce(collection, 0, iterator, function(err, res) { |
|
* console.log(res); // 10 |
|
* console.log(order); // [1, 3, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var collection = [1, 3, 2, 4]; |
|
* var iterator = function(result, num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, result + num); |
|
* }, num * 10); |
|
* }; |
|
* async.reduce(collection, '', iterator, function(err, res) { |
|
* console.log(res); // '1324' |
|
* console.log(order); // [[1, 0], [3, 1], [2, 2], [4, 3]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2, d: 4 }; |
|
* var iterator = function(result, num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, result + num); |
|
* }, num * 10); |
|
* }; |
|
* async.reduce(collection, '', iterator, function(err, res) { |
|
* console.log(res); // '1324' |
|
* console.log(order); // [1, 3, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2, d: 4 }; |
|
* var iterator = function(result, num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, result + num); |
|
* }, num * 10); |
|
* }; |
|
* async.reduce(collection, 0, iterator, function(err, res) { |
|
* console.log(res); // 10 |
|
* console.log(order); // [[1, 'a'], [3, 'b'], [2, 'b'], [4, 'd']] |
|
* }); |
|
* |
|
*/ |
|
function reduce(collection, result, iterator, callback) { |
|
callback = onlyOnce(callback || noop); |
|
var size, key, keys, iter, item, iterate; |
|
var sync = false; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = Infinity; |
|
iter = collection[iteratorSymbol](); |
|
iterate = iterator.length === 4 ? symbolIteratorWithKey : symbolIterator; |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
iterate = iterator.length === 4 ? objectIteratorWithKey : objectIterator; |
|
} |
|
if (!size) { |
|
return callback(null, result); |
|
} |
|
iterate(result); |
|
|
|
function arrayIterator(result) { |
|
iterator(result, collection[completed], done); |
|
} |
|
|
|
function arrayIteratorWithIndex(result) { |
|
iterator(result, collection[completed], completed, done); |
|
} |
|
|
|
function symbolIterator(result) { |
|
item = iter.next(); |
|
item.done ? callback(null, result) : iterator(result, item.value, done); |
|
} |
|
|
|
function symbolIteratorWithKey(result) { |
|
item = iter.next(); |
|
item.done ? callback(null, result) : iterator(result, item.value, completed, done); |
|
} |
|
|
|
function objectIterator(result) { |
|
iterator(result, collection[keys[completed]], done); |
|
} |
|
|
|
function objectIteratorWithKey(result) { |
|
key = keys[completed]; |
|
iterator(result, collection[key], key, done); |
|
} |
|
|
|
function done(err, result) { |
|
if (err) { |
|
callback(err, result); |
|
} else if (++completed === size) { |
|
iterator = throwError; |
|
callback(null, result); |
|
} else if (sync) { |
|
nextTick(function() { |
|
iterate(result); |
|
}); |
|
} else { |
|
sync = true; |
|
iterate(result); |
|
} |
|
sync = false; |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace reduceRight |
|
* @param {Array|Object} collection |
|
* @param {*} result |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var collection = [1, 3, 2, 4]; |
|
* var iterator = function(result, num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, result + num); |
|
* }, num * 10); |
|
* }; |
|
* async.reduceRight(collection, 0, iterator, function(err, res) { |
|
* console.log(res); // 10 |
|
* console.log(order); // [4, 2, 3, 1] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var collection = [1, 3, 2, 4]; |
|
* var iterator = function(result, num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, result + num); |
|
* }, num * 10); |
|
* }; |
|
* async.reduceRight(collection, '', iterator, function(err, res) { |
|
* console.log(res); // '4231' |
|
* console.log(order); // [[4, 3], [2, 2], [3, 1], [1, 0]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2, d: 4 }; |
|
* var iterator = function(result, num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, result + num); |
|
* }, num * 10); |
|
* }; |
|
* async.reduceRight(collection, '', iterator, function(err, res) { |
|
* console.log(res); // '4231' |
|
* console.log(order); // [4, 2, 3, 1] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2, d: 4 }; |
|
* var iterator = function(result, num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, result + num); |
|
* }, num * 10); |
|
* }; |
|
* async.reduceRight(collection, 0, iterator, function(err, res) { |
|
* console.log(res); // 10 |
|
* console.log(order); // [[4, 3], [2, 2], [3, 1], [1, 0]] |
|
* }); |
|
* |
|
*/ |
|
function reduceRight(collection, result, iterator, callback) { |
|
callback = onlyOnce(callback || noop); |
|
var resIndex, index, key, keys, iter, item, col, iterate; |
|
var sync = false; |
|
|
|
if (isArray(collection)) { |
|
resIndex = collection.length; |
|
iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
col = []; |
|
iter = collection[iteratorSymbol](); |
|
index = -1; |
|
while ((item = iter.next()).done === false) { |
|
col[++index] = item.value; |
|
} |
|
collection = col; |
|
resIndex = col.length; |
|
iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
resIndex = keys.length; |
|
iterate = iterator.length === 4 ? objectIteratorWithKey : objectIterator; |
|
} |
|
if (!resIndex) { |
|
return callback(null, result); |
|
} |
|
iterate(result); |
|
|
|
function arrayIterator(result) { |
|
iterator(result, collection[--resIndex], done); |
|
} |
|
|
|
function arrayIteratorWithIndex(result) { |
|
iterator(result, collection[--resIndex], resIndex, done); |
|
} |
|
|
|
function objectIterator(result) { |
|
iterator(result, collection[keys[--resIndex]], done); |
|
} |
|
|
|
function objectIteratorWithKey(result) { |
|
key = keys[--resIndex]; |
|
iterator(result, collection[key], key, done); |
|
} |
|
|
|
function done(err, result) { |
|
if (err) { |
|
callback(err, result); |
|
} else if (resIndex === 0) { |
|
iterate = throwError; |
|
callback(null, result); |
|
} else if (sync) { |
|
nextTick(function() { |
|
iterate(result); |
|
}); |
|
} else { |
|
sync = true; |
|
iterate(result); |
|
} |
|
sync = false; |
|
} |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {Function} arrayEach |
|
* @param {Function} baseEach |
|
* @param {Function} symbolEach |
|
*/ |
|
function createTransform(arrayEach, baseEach, symbolEach) { |
|
return function transform(collection, accumulator, iterator, callback) { |
|
if (arguments.length === 3) { |
|
callback = iterator; |
|
iterator = accumulator; |
|
accumulator = undefined; |
|
} |
|
callback = callback || noop; |
|
var size, keys, result; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
result = accumulator !== undefined ? accumulator : []; |
|
arrayEach(collection, result, iterator, done); |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
result = accumulator !== undefined ? accumulator : {}; |
|
size = symbolEach(collection, result, iterator, done); |
|
size && size === completed && callback(null, result); |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
result = accumulator !== undefined ? accumulator : {}; |
|
baseEach(collection, result, iterator, done, keys); |
|
} |
|
if (!size) { |
|
callback(null, accumulator !== undefined ? accumulator : result || {}); |
|
} |
|
|
|
function done(err, bool) { |
|
if (err) { |
|
callback = once(callback); |
|
callback(err, isArray(result) ? createArray(result) : objectClone(result)); |
|
} else if (++completed === size) { |
|
callback(null, result); |
|
} else if (bool === false) { |
|
callback = once(callback); |
|
callback(null, isArray(result) ? createArray(result) : objectClone(result)); |
|
} |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace transformSeries |
|
* @param {Array|Object} collection |
|
* @param {Array|Object|Function} [accumulator] |
|
* @param {Function} [iterator] |
|
* @param {Function} [callback] |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var collection = [1, 3, 2, 4]; |
|
* var iterator = function(result, num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* result.push(num) |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.transformSeries(collection, iterator, function(err, res) { |
|
* console.log(res); // [1, 3, 2, 4] |
|
* console.log(order); // [1, 3, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index and accumulator |
|
* var order = []; |
|
* var collection = [1, 3, 2, 4]; |
|
* var iterator = function(result, num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* result[index] = num; |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.transformSeries(collection, {}, iterator, function(err, res) { |
|
* console.log(res); // { '0': 1, '1': 3, '2': 2, '3': 4 } |
|
* console.log(order); // [[1, 0], [3, 1], [2, 2], [4, 3]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with accumulator |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2, d: 4 }; |
|
* var iterator = function(result, num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* result.push(num); |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.transformSeries(collection, [], iterator, function(err, res) { |
|
* console.log(res); // [1, 3, 2, 4] |
|
* console.log(order); // [1, 3, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2, d: 4 }; |
|
* var iterator = function(result, num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* result[key] = num; |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.transformSeries(collection, iterator, function(err, res) { |
|
* console.log(res); // { a: 1, b: 3, c: 2, d: 4 } |
|
* console.log(order); // [[1, 'a'], [3, 'b'], [2, 'b'], [4, 'd']] |
|
* }); |
|
* |
|
*/ |
|
function transformSeries(collection, accumulator, iterator, callback) { |
|
if (arguments.length === 3) { |
|
callback = iterator; |
|
iterator = accumulator; |
|
accumulator = undefined; |
|
} |
|
callback = onlyOnce(callback || noop); |
|
var size, key, keys, iter, item, iterate, result; |
|
var sync = false; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
result = accumulator !== undefined ? accumulator : []; |
|
iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = Infinity; |
|
iter = collection[iteratorSymbol](); |
|
result = accumulator !== undefined ? accumulator : {}; |
|
iterate = iterator.length === 4 ? symbolIteratorWithKey : symbolIterator; |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
result = accumulator !== undefined ? accumulator : {}; |
|
iterate = iterator.length === 4 ? objectIteratorWithKey : objectIterator; |
|
} |
|
if (!size) { |
|
return callback(null, accumulator !== undefined ? accumulator : result || {}); |
|
} |
|
iterate(); |
|
|
|
function arrayIterator() { |
|
iterator(result, collection[completed], done); |
|
} |
|
|
|
function arrayIteratorWithIndex() { |
|
iterator(result, collection[completed], completed, done); |
|
} |
|
|
|
function symbolIterator() { |
|
item = iter.next(); |
|
item.done ? callback(null, result) : iterator(result, item.value, done); |
|
} |
|
|
|
function symbolIteratorWithKey() { |
|
item = iter.next(); |
|
item.done ? callback(null, result) : iterator(result, item.value, completed, done); |
|
} |
|
|
|
function objectIterator() { |
|
iterator(result, collection[keys[completed]], done); |
|
} |
|
|
|
function objectIteratorWithKey() { |
|
key = keys[completed]; |
|
iterator(result, collection[key], key, done); |
|
} |
|
|
|
function done(err, bool) { |
|
if (err) { |
|
callback(err, result); |
|
} else if (++completed === size || bool === false) { |
|
iterate = throwError; |
|
callback(null, result); |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace transformLimit |
|
* @param {Array|Object} collection |
|
* @param {number} limit - limit >= 1 |
|
* @param {Array|Object|Function} [accumulator] |
|
* @param {Function} [iterator] |
|
* @param {Function} [callback] |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(result, num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* result.push(num); |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.transformLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // [1, 3, 5, 2, 4] |
|
* console.log(order); // [1, 3, 5, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index and accumulator |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(result, num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* result[index] = key; |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.transformLimit(array, 2, {}, iterator, function(err, res) { |
|
* console.log(res); // { '0': 1, '1': 5, '2': 3, '3': 4, '4': 2 } |
|
* console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with accumulator |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(result, num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* result.push(num); |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.transformLimit(object, 2, [], iterator, function(err, res) { |
|
* console.log(res); // [1, 3, 5, 2, 4] |
|
* console.log(order); // [1, 3, 5, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(result, num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* result[key] = num; |
|
* done(); |
|
* }, num * 10); |
|
* }; |
|
* async.transformLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']] |
|
* }); |
|
* |
|
*/ |
|
function transformLimit(collection, limit, accumulator, iterator, callback) { |
|
if (arguments.length === 4) { |
|
callback = iterator; |
|
iterator = accumulator; |
|
accumulator = undefined; |
|
} |
|
callback = callback || noop; |
|
var size, index, key, keys, iter, item, iterate, result; |
|
var sync = false; |
|
var started = 0; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
result = accumulator !== undefined ? accumulator : []; |
|
iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = Infinity; |
|
iter = collection[iteratorSymbol](); |
|
result = accumulator !== undefined ? accumulator : {}; |
|
iterate = iterator.length === 4 ? symbolIteratorWithKey : symbolIterator; |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
result = accumulator !== undefined ? accumulator : {}; |
|
iterate = iterator.length === 4 ? objectIteratorWithKey : objectIterator; |
|
} |
|
if (!size || isNaN(limit) || limit < 1) { |
|
return callback(null, accumulator !== undefined ? accumulator : result || {}); |
|
} |
|
timesSync(limit > size ? size : limit, iterate); |
|
|
|
function arrayIterator() { |
|
index = started++; |
|
if (index < size) { |
|
iterator(result, collection[index], onlyOnce(done)); |
|
} |
|
} |
|
|
|
function arrayIteratorWithIndex() { |
|
index = started++; |
|
if (index < size) { |
|
iterator(result, collection[index], index, onlyOnce(done)); |
|
} |
|
} |
|
|
|
function symbolIterator() { |
|
item = iter.next(); |
|
if (item.done === false) { |
|
started++; |
|
iterator(result, item.value, onlyOnce(done)); |
|
} else if (completed === started && iterator !== noop) { |
|
iterator = noop; |
|
callback(null, result); |
|
} |
|
} |
|
|
|
function symbolIteratorWithKey() { |
|
item = iter.next(); |
|
if (item.done === false) { |
|
iterator(result, item.value, started++, onlyOnce(done)); |
|
} else if (completed === started && iterator !== noop) { |
|
iterator = noop; |
|
callback(null, result); |
|
} |
|
} |
|
|
|
function objectIterator() { |
|
index = started++; |
|
if (index < size) { |
|
iterator(result, collection[keys[index]], onlyOnce(done)); |
|
} |
|
} |
|
|
|
function objectIteratorWithKey() { |
|
index = started++; |
|
if (index < size) { |
|
key = keys[index]; |
|
iterator(result, collection[key], key, onlyOnce(done)); |
|
} |
|
} |
|
|
|
function done(err, bool) { |
|
if (err || bool === false) { |
|
iterate = noop; |
|
callback(err || null, isArray(result) ? createArray(result) : objectClone(result)); |
|
callback = noop; |
|
} else if (++completed === size) { |
|
iterator = noop; |
|
callback(null, result); |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
} |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {function} arrayEach |
|
* @param {function} baseEach |
|
* @param {function} symbolEach |
|
*/ |
|
function createSortBy(arrayEach, baseEach, symbolEach) { |
|
return function sortBy(collection, iterator, callback) { |
|
callback = callback || noop; |
|
var size, array, criteria; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
array = Array(size); |
|
criteria = Array(size); |
|
arrayEach(collection, iterator, createCallback); |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
array = []; |
|
criteria = []; |
|
size = symbolEach(collection, iterator, createCallback); |
|
size && size === completed && callback(null, sortByCriteria(array, criteria)); |
|
} else if (typeof collection === obj) { |
|
var keys = nativeKeys(collection); |
|
size = keys.length; |
|
array = Array(size); |
|
criteria = Array(size); |
|
baseEach(collection, iterator, createCallback, keys); |
|
} |
|
if (!size) { |
|
callback(null, []); |
|
} |
|
|
|
function createCallback(index, value) { |
|
var called = false; |
|
array[index] = value; |
|
return function done(err, criterion) { |
|
if (called) { |
|
throwError(); |
|
} |
|
called = true; |
|
criteria[index] = criterion; |
|
if (err) { |
|
callback = once(callback); |
|
callback(err); |
|
} else if (++completed === size) { |
|
callback(null, sortByCriteria(array, criteria)); |
|
} |
|
}; |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace sortBySeries |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.sortBySeries(array, iterator, function(err, res) { |
|
* console.log(res); // [1, 2, 3]; |
|
* console.log(order); // [1, 3, 2] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.sortBySeries(array, iterator, function(err, res) { |
|
* console.log(res); // [1, 2, 3] |
|
* console.log(order); // [[1, 0], [3, 1], [2, 2]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.sortBySeries(object, iterator, function(err, res) { |
|
* console.log(res); // [1, 2, 3] |
|
* console.log(order); // [1, 3, 2] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.sortBySeries(object, iterator, function(err, res) { |
|
* console.log(res); // [1, 2, 3] |
|
* console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']] |
|
* }); |
|
* |
|
*/ |
|
function sortBySeries(collection, iterator, callback) { |
|
callback = onlyOnce(callback || noop); |
|
var size, key, value, keys, iter, item, array, criteria, iterate; |
|
var sync = false; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
array = collection; |
|
criteria = Array(size); |
|
iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = Infinity; |
|
array = []; |
|
criteria = []; |
|
iter = collection[iteratorSymbol](); |
|
iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
array = Array(size); |
|
criteria = Array(size); |
|
iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; |
|
} |
|
if (!size) { |
|
return callback(null, []); |
|
} |
|
iterate(); |
|
|
|
function arrayIterator() { |
|
value = collection[completed]; |
|
iterator(value, done); |
|
} |
|
|
|
function arrayIteratorWithIndex() { |
|
value = collection[completed]; |
|
iterator(value, completed, done); |
|
} |
|
|
|
function symbolIterator() { |
|
item = iter.next(); |
|
if (item.done) { |
|
return callback(null, sortByCriteria(array, criteria)); |
|
} |
|
value = item.value; |
|
array[completed] = value; |
|
iterator(value, done); |
|
} |
|
|
|
function symbolIteratorWithKey() { |
|
item = iter.next(); |
|
if (item.done) { |
|
return callback(null, sortByCriteria(array, criteria)); |
|
} |
|
value = item.value; |
|
array[completed] = value; |
|
iterator(value, completed, done); |
|
} |
|
|
|
function objectIterator() { |
|
value = collection[keys[completed]]; |
|
array[completed] = value; |
|
iterator(value, done); |
|
} |
|
|
|
function objectIteratorWithKey() { |
|
key = keys[completed]; |
|
value = collection[key]; |
|
array[completed] = value; |
|
iterator(value, key, done); |
|
} |
|
|
|
function done(err, criterion) { |
|
criteria[completed] = criterion; |
|
if (err) { |
|
callback(err); |
|
} else if (++completed === size) { |
|
iterate = throwError; |
|
callback(null, sortByCriteria(array, criteria)); |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace sortByLimit |
|
* @param {Array|Object} collection |
|
* @param {number} limit - limit >= 1 |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.sortByLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // [1, 2, 3, 4, 5] |
|
* console.log(order); // [1, 3, 5, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.sortByLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // [1, 2, 3, 4, 5] |
|
* console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.sortByLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // [1, 2, 3, 4, 5] |
|
* console.log(order); // [1, 3, 5, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.sortByLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // [1, 2, 3, 4, 5] |
|
* console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']] |
|
* }); |
|
* |
|
*/ |
|
function sortByLimit(collection, limit, iterator, callback) { |
|
callback = callback || noop; |
|
var size, index, key, value, array, keys, iter, item, criteria, iterate; |
|
var sync = false; |
|
var started = 0; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
array = collection; |
|
iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = Infinity; |
|
iter = collection[iteratorSymbol](); |
|
array = []; |
|
criteria = []; |
|
iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
array = Array(size); |
|
iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; |
|
} |
|
if (!size || isNaN(limit) || limit < 1) { |
|
return callback(null, []); |
|
} |
|
criteria = criteria || Array(size); |
|
timesSync(limit > size ? size : limit, iterate); |
|
|
|
function arrayIterator() { |
|
if (started < size) { |
|
value = collection[started]; |
|
iterator(value, createCallback(value, started++)); |
|
} |
|
} |
|
|
|
function arrayIteratorWithIndex() { |
|
index = started++; |
|
if (index < size) { |
|
value = collection[index]; |
|
iterator(value, index, createCallback(value, index)); |
|
} |
|
} |
|
|
|
function symbolIterator() { |
|
item = iter.next(); |
|
if (item.done === false) { |
|
value = item.value; |
|
array[started] = value; |
|
iterator(value, createCallback(value, started++)); |
|
} else if (completed === started && iterator !== noop) { |
|
iterator = noop; |
|
callback(null, sortByCriteria(array, criteria)); |
|
} |
|
} |
|
|
|
function symbolIteratorWithKey() { |
|
item = iter.next(); |
|
if (item.done === false) { |
|
value = item.value; |
|
array[started] = value; |
|
iterator(value, started, createCallback(value, started++)); |
|
} else if (completed === started && iterator !== noop) { |
|
iterator = noop; |
|
callback(null, sortByCriteria(array, criteria)); |
|
} |
|
} |
|
|
|
function objectIterator() { |
|
if (started < size) { |
|
value = collection[keys[started]]; |
|
array[started] = value; |
|
iterator(value, createCallback(value, started++)); |
|
} |
|
} |
|
|
|
function objectIteratorWithKey() { |
|
if (started < size) { |
|
key = keys[started]; |
|
value = collection[key]; |
|
array[started] = value; |
|
iterator(value, key, createCallback(value, started++)); |
|
} |
|
} |
|
|
|
function createCallback(value, index) { |
|
var called = false; |
|
return function(err, criterion) { |
|
if (called) { |
|
throwError(); |
|
} |
|
called = true; |
|
criteria[index] = criterion; |
|
if (err) { |
|
iterate = noop; |
|
callback(err); |
|
callback = noop; |
|
} else if (++completed === size) { |
|
callback(null, sortByCriteria(array, criteria)); |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
}; |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace some |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.some(array, iterator, function(err, res) { |
|
* console.log(res); // true |
|
* console.log(order); // [1] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.some(array, iterator, function(err, res) { |
|
* console.log(res); // true |
|
* console.log(order); // [[1, 0]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.some(object, iterator, function(err, res) { |
|
* console.log(res); // true |
|
* console.log(order); // [1] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.some(object, iterator, function(err, res) { |
|
* console.log(res); // true |
|
* console.log(order); // [[1, 'a']] |
|
* }); |
|
* |
|
*/ |
|
function some(collection, iterator, callback) { |
|
callback = callback || noop; |
|
detect(collection, iterator, done); |
|
|
|
function done(err, res) { |
|
if (err) { |
|
return callback(err); |
|
} |
|
callback(null, !!res); |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace someSeries |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.someSeries(array, iterator, function(err, res) { |
|
* console.log(res); // true |
|
* console.log(order); // [1] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.someSeries(array, iterator, function(err, res) { |
|
* console.log(res); // true |
|
* console.log(order); // [[1, 0]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.someSeries(object, iterator, function(err, res) { |
|
* console.log(res); // true |
|
* console.log(order); // [1] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.someSeries(object, iterator, function(err, res) { |
|
* console.log(res); // true |
|
* console.log(order); // [[1, 'a']] |
|
* }); |
|
* |
|
*/ |
|
function someSeries(collection, iterator, callback) { |
|
callback = callback || noop; |
|
detectSeries(collection, iterator, done); |
|
|
|
function done(err, res) { |
|
if (err) { |
|
return callback(err); |
|
} |
|
callback(null, !!res); |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace someLimit |
|
* @param {Array|Object} collection |
|
* @param {number} limit - limit >= 1 |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.someLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // true |
|
* console.log(order); // [1] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.someLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // true |
|
* console.log(order); // [[1, 0]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.someLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // true |
|
* console.log(order); // [1] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num % 2); |
|
* }, num * 10); |
|
* }; |
|
* async.someLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // true |
|
* console.log(order); // [[1, 'a']] |
|
* }); |
|
* |
|
*/ |
|
function someLimit(collection, limit, iterator, callback) { |
|
callback = callback || noop; |
|
detectLimit(collection, limit, iterator, done); |
|
|
|
function done(err, res) { |
|
if (err) { |
|
return callback(err); |
|
} |
|
callback(null, !!res); |
|
} |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {Function} arrayEach |
|
* @param {Function} baseEach |
|
* @param {Function} symbolEach |
|
*/ |
|
function createEvery(arrayEach, baseEach, symbolEach) { |
|
var deny = createDetect(arrayEach, baseEach, symbolEach, false); |
|
|
|
return function every(collection, iterator, callback) { |
|
callback = callback || noop; |
|
deny(collection, iterator, done); |
|
|
|
function done(err, res) { |
|
if (err) { |
|
return callback(err); |
|
} |
|
callback(null, !res); |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function createEverySeries() { |
|
var denySeries = createDetectSeries(false); |
|
|
|
return function everySeries(collection, iterator, callback) { |
|
callback = callback || noop; |
|
denySeries(collection, iterator, done); |
|
|
|
function done(err, res) { |
|
if (err) { |
|
return callback(err); |
|
} |
|
callback(null, !res); |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @private |
|
*/ |
|
function createEveryLimit() { |
|
var denyLimit = createDetectLimit(false); |
|
|
|
return function everyLimit(collection, limit, iterator, callback) { |
|
callback = callback || noop; |
|
denyLimit(collection, limit, iterator, done); |
|
|
|
function done(err, res) { |
|
if (err) { |
|
return callback(err); |
|
} |
|
callback(null, !res); |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {Function} arrayEach |
|
* @param {Function} baseEach |
|
* @param {Function} symbolEach |
|
*/ |
|
function createConcat(arrayEach, baseEach, symbolEach) { |
|
return function concat(collection, iterator, callback) { |
|
callback = callback || noop; |
|
var size, result; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
result = Array(size); |
|
arrayEach(collection, iterator, createCallback); |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
result = []; |
|
size = symbolEach(collection, iterator, createCallback); |
|
size && size === completed && callback(null, result); |
|
} else if (typeof collection === obj) { |
|
var keys = nativeKeys(collection); |
|
size = keys.length; |
|
result = Array(size); |
|
baseEach(collection, iterator, createCallback, keys); |
|
} |
|
if (!size) { |
|
callback(null, []); |
|
} |
|
|
|
function createCallback(index) { |
|
return function done(err, res) { |
|
if (index === null) { |
|
throwError(); |
|
} |
|
if (err) { |
|
index = null; |
|
callback = once(callback); |
|
arrayEachSync(result, function(array, index) { |
|
if (array === undefined) { |
|
result[index] = noop; |
|
} |
|
}); |
|
callback(err, makeConcatResult(result)); |
|
return; |
|
} |
|
switch (arguments.length) { |
|
case 0: |
|
case 1: |
|
result[index] = noop; |
|
break; |
|
case 2: |
|
result[index] = res; |
|
break; |
|
default: |
|
result[index] = slice(arguments, 1); |
|
break; |
|
} |
|
index = null; |
|
if (++completed === size) { |
|
callback(null, makeConcatResult(result)); |
|
} |
|
}; |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace concatSeries |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, [num]); |
|
* }, num * 10); |
|
* }; |
|
* async.concatSeries(array, iterator, function(err, res) { |
|
* console.log(res); // [1, 3, 2]; |
|
* console.log(order); // [1, 3, 2] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 3, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, [num]); |
|
* }, num * 10); |
|
* }; |
|
* async.concatSeries(array, iterator, function(err, res) { |
|
* console.log(res); // [1, 3, 2] |
|
* console.log(order); // [[1, 0], [3, 1], [2, 2]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, [num]); |
|
* }, num * 10); |
|
* }; |
|
* async.concatSeries(object, iterator, function(err, res) { |
|
* console.log(res); // [1, 3, 2] |
|
* console.log(order); // [1, 3, 2] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 3, c: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, [num]); |
|
* }, num * 10); |
|
* }; |
|
* async.concatSeries(object, iterator, function(err, res) { |
|
* console.log(res); // [1, 3, 2] |
|
* console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']] |
|
* }); |
|
* |
|
*/ |
|
function concatSeries(collection, iterator, callback) { |
|
callback = onlyOnce(callback || noop); |
|
var size, key, keys, iter, item, iterate; |
|
var sync = false; |
|
var result = []; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = Infinity; |
|
iter = collection[iteratorSymbol](); |
|
iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; |
|
} |
|
if (!size) { |
|
return callback(null, result); |
|
} |
|
iterate(); |
|
|
|
function arrayIterator() { |
|
iterator(collection[completed], done); |
|
} |
|
|
|
function arrayIteratorWithIndex() { |
|
iterator(collection[completed], completed, done); |
|
} |
|
|
|
function symbolIterator() { |
|
item = iter.next(); |
|
item.done ? callback(null, result) : iterator(item.value, done); |
|
} |
|
|
|
function symbolIteratorWithKey() { |
|
item = iter.next(); |
|
item.done ? callback(null, result) : iterator(item.value, completed, done); |
|
} |
|
|
|
function objectIterator() { |
|
iterator(collection[keys[completed]], done); |
|
} |
|
|
|
function objectIteratorWithKey() { |
|
key = keys[completed]; |
|
iterator(collection[key], key, done); |
|
} |
|
|
|
function done(err, array) { |
|
if (isArray(array)) { |
|
nativePush.apply(result, array); |
|
} else if (arguments.length >= 2) { |
|
nativePush.apply(result, slice(arguments, 1)); |
|
} |
|
if (err) { |
|
callback(err, result); |
|
} else if (++completed === size) { |
|
iterate = throwError; |
|
callback(null, result); |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace concatLimit |
|
* @param {Array|Object} collection |
|
* @param {number} limit - limit >= 1 |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, [num]); |
|
* }, num * 10); |
|
* }; |
|
* async.concatLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // [1, 3, 5, 2, 4] |
|
* console.log(order); // [1, 3, 5, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1, 5, 3, 4, 2]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, [num]); |
|
* }, num * 10); |
|
* }; |
|
* async.cocnatLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // [1, 3, 5, 2, 4] |
|
* console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, [num]); |
|
* }, num * 10); |
|
* }; |
|
* async.concatLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // [1, 3, 5, 2, 4] |
|
* console.log(order); // [1, 3, 5, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, num); |
|
* }, num * 10); |
|
* }; |
|
* async.cocnatLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // [1, 3, 5, 2, 4] |
|
* console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']] |
|
* }); |
|
* |
|
*/ |
|
function concatLimit(collection, limit, iterator, callback) { |
|
callback = callback || noop; |
|
var size, key, iter, item, iterate, result; |
|
var sync = false; |
|
var started = 0; |
|
var completed = 0; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = Infinity; |
|
result = []; |
|
iter = collection[iteratorSymbol](); |
|
iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; |
|
} else if (typeof collection === obj) { |
|
var keys = nativeKeys(collection); |
|
size = keys.length; |
|
iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; |
|
} |
|
if (!size || isNaN(limit) || limit < 1) { |
|
return callback(null, []); |
|
} |
|
result = result || Array(size); |
|
timesSync(limit > size ? size : limit, iterate); |
|
|
|
function arrayIterator() { |
|
if (started < size) { |
|
iterator(collection[started], createCallback(started++)); |
|
} |
|
} |
|
|
|
function arrayIteratorWithIndex() { |
|
if (started < size) { |
|
iterator(collection[started], started, createCallback(started++)); |
|
} |
|
} |
|
|
|
function symbolIterator() { |
|
item = iter.next(); |
|
if (item.done === false) { |
|
iterator(item.value, createCallback(started++)); |
|
} else if (completed === started && iterator !== noop) { |
|
iterator = noop; |
|
callback(null, makeConcatResult(result)); |
|
} |
|
} |
|
|
|
function symbolIteratorWithKey() { |
|
item = iter.next(); |
|
if (item.done === false) { |
|
iterator(item.value, started, createCallback(started++)); |
|
} else if (completed === started && iterator !== noop) { |
|
iterator = noop; |
|
callback(null, makeConcatResult(result)); |
|
} |
|
} |
|
|
|
function objectIterator() { |
|
if (started < size) { |
|
iterator(collection[keys[started]], createCallback(started++)); |
|
} |
|
} |
|
|
|
function objectIteratorWithKey() { |
|
if (started < size) { |
|
key = keys[started]; |
|
iterator(collection[key], key, createCallback(started++)); |
|
} |
|
} |
|
|
|
function createCallback(index) { |
|
return function(err, res) { |
|
if (index === null) { |
|
throwError(); |
|
} |
|
if (err) { |
|
index = null; |
|
iterate = noop; |
|
callback = once(callback); |
|
arrayEachSync(result, function(array, index) { |
|
if (array === undefined) { |
|
result[index] = noop; |
|
} |
|
}); |
|
callback(err, makeConcatResult(result)); |
|
return; |
|
} |
|
switch (arguments.length) { |
|
case 0: |
|
case 1: |
|
result[index] = noop; |
|
break; |
|
case 2: |
|
result[index] = res; |
|
break; |
|
default: |
|
result[index] = slice(arguments, 1); |
|
break; |
|
} |
|
index = null; |
|
if (++completed === size) { |
|
iterate = throwError; |
|
callback(null, makeConcatResult(result)); |
|
callback = throwError; |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
}; |
|
} |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {Function} arrayEach |
|
* @param {Function} baseEach |
|
* @param {Function} symbolEach |
|
*/ |
|
function createGroupBy(arrayEach, baseEach, symbolEach) { |
|
return function groupBy(collection, iterator, callback) { |
|
callback = callback || noop; |
|
var size; |
|
var completed = 0; |
|
var result = {}; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
arrayEach(collection, iterator, createCallback); |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = symbolEach(collection, iterator, createCallback); |
|
size && size === completed && callback(null, result); |
|
} else if (typeof collection === obj) { |
|
var keys = nativeKeys(collection); |
|
size = keys.length; |
|
baseEach(collection, iterator, createCallback, keys); |
|
} |
|
if (!size) { |
|
callback(null, {}); |
|
} |
|
|
|
function createCallback(value) { |
|
var called = false; |
|
return function done(err, key) { |
|
if (called) { |
|
throwError(); |
|
} |
|
called = true; |
|
if (err) { |
|
callback = once(callback); |
|
callback(err, objectClone(result)); |
|
return; |
|
} |
|
var array = result[key]; |
|
if (!array) { |
|
result[key] = [value]; |
|
} else { |
|
array.push(value); |
|
} |
|
if (++completed === size) { |
|
callback(null, result); |
|
} |
|
}; |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace groupBySeries |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [4.2, 6.4, 6.1]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, Math.floor(num)); |
|
* }, num * 10); |
|
* }; |
|
* async.groupBySeries(array, iterator, function(err, res) { |
|
* console.log(res); // { '4': [4.2], '6': [6.4, 6.1] } |
|
* console.log(order); // [4.2, 6.4, 6.1] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [4.2, 6.4, 6.1]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, Math.floor(num)); |
|
* }, num * 10); |
|
* }; |
|
* async.groupBySeries(array, iterator, function(err, res) { |
|
* console.log(res); // { '4': [4.2], '6': [6.4, 6.1] } |
|
* console.log(order); // [[4.2, 0], [6.4, 1], [6.1, 2]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 4.2, b: 6.4, c: 6.1 }; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, Math.floor(num)); |
|
* }, num * 10); |
|
* }; |
|
* async.groupBySeries(object, iterator, function(err, res) { |
|
* console.log(res); // { '4': [4.2], '6': [6.4, 6.1] } |
|
* console.log(order); // [4.2, 6.4, 6.1] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 4.2, b: 6.4, c: 6.1 }; |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, Math.floor(num)); |
|
* }, num * 10); |
|
* }; |
|
* async.groupBySeries(object, iterator, function(err, res) { |
|
* console.log(res); // { '4': [4.2], '6': [6.4, 6.1] } |
|
* console.log(order); // [[4.2, 'a'], [6.4, 'b'], [6.1, 'c']] |
|
* }); |
|
* |
|
*/ |
|
function groupBySeries(collection, iterator, callback) { |
|
callback = onlyOnce(callback || noop); |
|
var size, key, value, keys, iter, item, iterate; |
|
var sync = false; |
|
var completed = 0; |
|
var result = {}; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = Infinity; |
|
iter = collection[iteratorSymbol](); |
|
iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; |
|
} |
|
if (!size) { |
|
return callback(null, result); |
|
} |
|
iterate(); |
|
|
|
function arrayIterator() { |
|
value = collection[completed]; |
|
iterator(value, done); |
|
} |
|
|
|
function arrayIteratorWithIndex() { |
|
value = collection[completed]; |
|
iterator(value, completed, done); |
|
} |
|
|
|
function symbolIterator() { |
|
item = iter.next(); |
|
value = item.value; |
|
item.done ? callback(null, result) : iterator(value, done); |
|
} |
|
|
|
function symbolIteratorWithKey() { |
|
item = iter.next(); |
|
value = item.value; |
|
item.done ? callback(null, result) : iterator(value, completed, done); |
|
} |
|
|
|
function objectIterator() { |
|
value = collection[keys[completed]]; |
|
iterator(value, done); |
|
} |
|
|
|
function objectIteratorWithKey() { |
|
key = keys[completed]; |
|
value = collection[key]; |
|
iterator(value, key, done); |
|
} |
|
|
|
function done(err, key) { |
|
if (err) { |
|
iterate = throwError; |
|
callback = onlyOnce(callback); |
|
callback(err, objectClone(result)); |
|
return; |
|
} |
|
var array = result[key]; |
|
if (!array) { |
|
result[key] = [value]; |
|
} else { |
|
array.push(value); |
|
} |
|
if (++completed === size) { |
|
iterate = throwError; |
|
callback(null, result); |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace groupByLimit |
|
* @param {Array|Object} collection |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var order = []; |
|
* var array = [1.1, 5.9, 3.2, 3.9, 2.1]; |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, Math.floor(num)); |
|
* }, num * 10); |
|
* }; |
|
* async.groupByLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // { '1': [1.1], '3': [3.2, 3.9], '5': [5.9], '2': [2.1] } |
|
* console.log(order); // [1.1, 3.2, 5.9, 2.1, 3.9] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // array with index |
|
* var order = []; |
|
* var array = [1.1, 5.9, 3.2, 3.9, 2.1]; |
|
* var iterator = function(num, index, done) { |
|
* setTimeout(function() { |
|
* order.push([num, index]); |
|
* done(null, Math.floor(num)); |
|
* }, num * 10); |
|
* }; |
|
* async.groupByLimit(array, 2, iterator, function(err, res) { |
|
* console.log(res); // { '1': [1.1], '3': [3.2, 3.9], '5': [5.9], '2': [2.1] } |
|
* console.log(order); // [[1.1, 0], [3.2, 2], [5.9, 1], [2.1, 4], [3.9, 3]] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var order = []; |
|
* var object = { a: 1.1, b: 5.9, c: 3.2, d: 3.9, e: 2.1 } |
|
* var iterator = function(num, done) { |
|
* setTimeout(function() { |
|
* order.push(num); |
|
* done(null, Math.floor(num)); |
|
* }, num * 10); |
|
* }; |
|
* async.groupByLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // { '1': [1.1], '3': [3.2, 3.9], '5': [5.9], '2': [2.1] } |
|
* console.log(order); // [1.1, 3.2, 5.9, 2.1, 3.9] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object with key |
|
* var order = []; |
|
* var object = { a: 1.1, b: 5.9, c: 3.2, d: 3.9, e: 2.1 } |
|
* var iterator = function(num, key, done) { |
|
* setTimeout(function() { |
|
* order.push([num, key]); |
|
* done(null, Math.floor(num)); |
|
* }, num * 10); |
|
* }; |
|
* async.groupByLimit(object, 2, iterator, function(err, res) { |
|
* console.log(res); // { '1': [1.1], '3': [3.2, 3.9], '5': [5.9], '2': [2.1] } |
|
* console.log(order); // [[1.1, 'a'], [3.2, 'c'], [5.9, 'b'], [2.1, 'e'], [3.9, 'd']] |
|
* }); |
|
* |
|
*/ |
|
function groupByLimit(collection, limit, iterator, callback) { |
|
callback = callback || noop; |
|
var size, index, key, value, keys, iter, item, iterate; |
|
var sync = false; |
|
var started = 0; |
|
var completed = 0; |
|
var result = {}; |
|
|
|
if (isArray(collection)) { |
|
size = collection.length; |
|
iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; |
|
} else if (!collection) { |
|
} else if (iteratorSymbol && collection[iteratorSymbol]) { |
|
size = Infinity; |
|
iter = collection[iteratorSymbol](); |
|
iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; |
|
} else if (typeof collection === obj) { |
|
keys = nativeKeys(collection); |
|
size = keys.length; |
|
iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; |
|
} |
|
if (!size || isNaN(limit) || limit < 1) { |
|
return callback(null, result); |
|
} |
|
timesSync(limit > size ? size : limit, iterate); |
|
|
|
function arrayIterator() { |
|
if (started < size) { |
|
value = collection[started++]; |
|
iterator(value, createCallback(value)); |
|
} |
|
} |
|
|
|
function arrayIteratorWithIndex() { |
|
index = started++; |
|
if (index < size) { |
|
value = collection[index]; |
|
iterator(value, index, createCallback(value)); |
|
} |
|
} |
|
|
|
function symbolIterator() { |
|
item = iter.next(); |
|
if (item.done === false) { |
|
started++; |
|
value = item.value; |
|
iterator(value, createCallback(value)); |
|
} else if (completed === started && iterator !== noop) { |
|
iterator = noop; |
|
callback(null, result); |
|
} |
|
} |
|
|
|
function symbolIteratorWithKey() { |
|
item = iter.next(); |
|
if (item.done === false) { |
|
value = item.value; |
|
iterator(value, started++, createCallback(value)); |
|
} else if (completed === started && iterator !== noop) { |
|
iterator = noop; |
|
callback(null, result); |
|
} |
|
} |
|
|
|
function objectIterator() { |
|
if (started < size) { |
|
value = collection[keys[started++]]; |
|
iterator(value, createCallback(value)); |
|
} |
|
} |
|
|
|
function objectIteratorWithKey() { |
|
if (started < size) { |
|
key = keys[started++]; |
|
value = collection[key]; |
|
iterator(value, key, createCallback(value)); |
|
} |
|
} |
|
|
|
function createCallback(value) { |
|
var called = false; |
|
return function(err, key) { |
|
if (called) { |
|
throwError(); |
|
} |
|
called = true; |
|
if (err) { |
|
iterate = noop; |
|
callback = once(callback); |
|
callback(err, objectClone(result)); |
|
return; |
|
} |
|
var array = result[key]; |
|
if (!array) { |
|
result[key] = [value]; |
|
} else { |
|
array.push(value); |
|
} |
|
if (++completed === size) { |
|
callback(null, result); |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
}; |
|
} |
|
} |
|
|
|
/** |
|
* @private |
|
* @param {Function} arrayEach |
|
* @param {Function} baseEach |
|
*/ |
|
function createParallel(arrayEach, baseEach) { |
|
return function parallel(tasks, callback) { |
|
callback = callback || noop; |
|
var size, keys, result; |
|
var completed = 0; |
|
|
|
if (isArray(tasks)) { |
|
size = tasks.length; |
|
result = Array(size); |
|
arrayEach(tasks, createCallback); |
|
} else if (tasks && typeof tasks === obj) { |
|
keys = nativeKeys(tasks); |
|
size = keys.length; |
|
result = {}; |
|
baseEach(tasks, createCallback, keys); |
|
} |
|
if (!size) { |
|
callback(null, result); |
|
} |
|
|
|
function createCallback(key) { |
|
return function(err, res) { |
|
if (key === null) { |
|
throwError(); |
|
} |
|
if (err) { |
|
key = null; |
|
callback = once(callback); |
|
callback(err, result); |
|
return; |
|
} |
|
result[key] = arguments.length <= 2 ? res : slice(arguments, 1); |
|
key = null; |
|
if (++completed === size) { |
|
callback(null, result); |
|
} |
|
}; |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace series |
|
* @param {Array|Object} tasks - functions |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* var order = []; |
|
* var tasks = [ |
|
* function(done) { |
|
* setTimeout(function() { |
|
* order.push(1); |
|
* done(null, 1); |
|
* }, 10); |
|
* }, |
|
* function(done) { |
|
* setTimeout(function() { |
|
* order.push(2); |
|
* done(null, 2); |
|
* }, 30); |
|
* }, |
|
* function(done) { |
|
* setTimeout(function() { |
|
* order.push(3); |
|
* done(null, 3); |
|
* }, 40); |
|
* }, |
|
* function(done) { |
|
* setTimeout(function() { |
|
* order.push(4); |
|
* done(null, 4); |
|
* }, 20); |
|
* } |
|
* ]; |
|
* async.series(tasks, function(err, res) { |
|
* console.log(res); // [1, 2, 3, 4]; |
|
* console.log(order); // [1, 2, 3, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* var order = []; |
|
* var tasks = { |
|
* 'a': function(done) { |
|
* setTimeout(function() { |
|
* order.push(1); |
|
* done(null, 1); |
|
* }, 10); |
|
* }, |
|
* 'b': function(done) { |
|
* setTimeout(function() { |
|
* order.push(2); |
|
* done(null, 2); |
|
* }, 30); |
|
* }, |
|
* 'c': function(done) { |
|
* setTimeout(function() { |
|
* order.push(3); |
|
* done(null, 3); |
|
* }, 40); |
|
* }, |
|
* 'd': function(done) { |
|
* setTimeout(function() { |
|
* order.push(4); |
|
* done(null, 4); |
|
* }, 20); |
|
* } |
|
* }; |
|
* async.series(tasks, function(err, res) { |
|
* console.log(res); // { a: 1, b: 2, c: 3, d:4 } |
|
* console.log(order); // [1, 4, 2, 3] |
|
* }); |
|
* |
|
*/ |
|
function series(tasks, callback) { |
|
callback = callback || noop; |
|
var size, key, keys, result, iterate; |
|
var sync = false; |
|
var completed = 0; |
|
|
|
if (isArray(tasks)) { |
|
size = tasks.length; |
|
result = Array(size); |
|
iterate = arrayIterator; |
|
} else if (tasks && typeof tasks === obj) { |
|
keys = nativeKeys(tasks); |
|
size = keys.length; |
|
result = {}; |
|
iterate = objectIterator; |
|
} else { |
|
return callback(null); |
|
} |
|
if (!size) { |
|
return callback(null, result); |
|
} |
|
iterate(); |
|
|
|
function arrayIterator() { |
|
key = completed; |
|
tasks[completed](done); |
|
} |
|
|
|
function objectIterator() { |
|
key = keys[completed]; |
|
tasks[key](done); |
|
} |
|
|
|
function done(err, res) { |
|
if (err) { |
|
iterate = throwError; |
|
callback = onlyOnce(callback); |
|
callback(err, result); |
|
return; |
|
} |
|
result[key] = arguments.length <= 2 ? res : slice(arguments, 1); |
|
if (++completed === size) { |
|
iterate = throwError; |
|
callback(null, result); |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace parallelLimit |
|
* @param {Array|Object} tasks - functions |
|
* @param {number} limit - limit >= 1 |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* var order = []; |
|
* var tasks = [ |
|
* function(done) { |
|
* setTimeout(function() { |
|
* order.push(1); |
|
* done(null, 1); |
|
* }, 10); |
|
* }, |
|
* function(done) { |
|
* setTimeout(function() { |
|
* order.push(2); |
|
* done(null, 2); |
|
* }, 50); |
|
* }, |
|
* function(done) { |
|
* setTimeout(function() { |
|
* order.push(3); |
|
* done(null, 3); |
|
* }, 30); |
|
* }, |
|
* function(done) { |
|
* setTimeout(function() { |
|
* order.push(4); |
|
* done(null, 4); |
|
* }, 40); |
|
* } |
|
* ]; |
|
* async.parallelLimit(tasks, 2, function(err, res) { |
|
* console.log(res); // [1, 2, 3, 4]; |
|
* console.log(order); // [1, 3, 2, 4] |
|
* }); |
|
* |
|
* @example |
|
* |
|
* var order = []; |
|
* var tasks = { |
|
* 'a': function(done) { |
|
* setTimeout(function() { |
|
* order.push(1); |
|
* done(null, 1); |
|
* }, 10); |
|
* }, |
|
* 'b': function(done) { |
|
* setTimeout(function() { |
|
* order.push(2); |
|
* done(null, 2); |
|
* }, 50); |
|
* }, |
|
* 'c': function(done) { |
|
* setTimeout(function() { |
|
* order.push(3); |
|
* done(null, 3); |
|
* }, 20); |
|
* }, |
|
* 'd': function(done) { |
|
* setTimeout(function() { |
|
* order.push(4); |
|
* done(null, 4); |
|
* }, 40); |
|
* } |
|
* }; |
|
* async.parallelLimit(tasks, 2, function(err, res) { |
|
* console.log(res); // { a: 1, b: 2, c: 3, d:4 } |
|
* console.log(order); // [1, 3, 2, 4] |
|
* }); |
|
* |
|
*/ |
|
function parallelLimit(tasks, limit, callback) { |
|
callback = callback || noop; |
|
var size, index, key, keys, result, iterate; |
|
var sync = false; |
|
var started = 0; |
|
var completed = 0; |
|
|
|
if (isArray(tasks)) { |
|
size = tasks.length; |
|
result = Array(size); |
|
iterate = arrayIterator; |
|
} else if (tasks && typeof tasks === obj) { |
|
keys = nativeKeys(tasks); |
|
size = keys.length; |
|
result = {}; |
|
iterate = objectIterator; |
|
} |
|
if (!size || isNaN(limit) || limit < 1) { |
|
return callback(null, result); |
|
} |
|
timesSync(limit > size ? size : limit, iterate); |
|
|
|
function arrayIterator() { |
|
index = started++; |
|
if (index < size) { |
|
tasks[index](createCallback(index)); |
|
} |
|
} |
|
|
|
function objectIterator() { |
|
if (started < size) { |
|
key = keys[started++]; |
|
tasks[key](createCallback(key)); |
|
} |
|
} |
|
|
|
function createCallback(key) { |
|
return function(err, res) { |
|
if (key === null) { |
|
throwError(); |
|
} |
|
if (err) { |
|
key = null; |
|
iterate = noop; |
|
callback = once(callback); |
|
callback(err, result); |
|
return; |
|
} |
|
result[key] = arguments.length <= 2 ? res : slice(arguments, 1); |
|
key = null; |
|
if (++completed === size) { |
|
callback(null, result); |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
}; |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace tryEach |
|
* @param {Array|Object} tasks - functions |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* var tasks = [ |
|
* function(done) { |
|
* setTimeout(function() { |
|
* done(new Error('error')); |
|
* }, 10); |
|
* }, |
|
* function(done) { |
|
* setTimeout(function() { |
|
* done(null, 2); |
|
* }, 10); |
|
* } |
|
* ]; |
|
* async.tryEach(tasks, function(err, res) { |
|
* console.log(res); // 2 |
|
* }); |
|
* |
|
* @example |
|
* |
|
* var tasks = [ |
|
* function(done) { |
|
* setTimeout(function() { |
|
* done(new Error('error1')); |
|
* }, 10); |
|
* }, |
|
* function(done) { |
|
* setTimeout(function() { |
|
* done(new Error('error2'); |
|
* }, 10); |
|
* } |
|
* ]; |
|
* async.tryEach(tasks, function(err, res) { |
|
* console.log(err); // error2 |
|
* console.log(res); // undefined |
|
* }); |
|
* |
|
*/ |
|
function tryEach(tasks, callback) { |
|
callback = callback || noop; |
|
var size, keys, iterate; |
|
var sync = false; |
|
var completed = 0; |
|
|
|
if (isArray(tasks)) { |
|
size = tasks.length; |
|
iterate = arrayIterator; |
|
} else if (tasks && typeof tasks === obj) { |
|
keys = nativeKeys(tasks); |
|
size = keys.length; |
|
iterate = objectIterator; |
|
} |
|
if (!size) { |
|
return callback(null); |
|
} |
|
iterate(); |
|
|
|
function arrayIterator() { |
|
tasks[completed](done); |
|
} |
|
|
|
function objectIterator() { |
|
tasks[keys[completed]](done); |
|
} |
|
|
|
function done(err, res) { |
|
if (!err) { |
|
if (arguments.length <= 2) { |
|
callback(null, res); |
|
} else { |
|
callback(null, slice(arguments, 1)); |
|
} |
|
} else if (++completed === size) { |
|
callback(err); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
} |
|
} |
|
|
|
/** |
|
* check for waterfall tasks |
|
* @private |
|
* @param {Array} tasks |
|
* @param {Function} callback |
|
* @return {boolean} |
|
*/ |
|
function checkWaterfallTasks(tasks, callback) { |
|
if (!isArray(tasks)) { |
|
callback(new Error('First argument to waterfall must be an array of functions')); |
|
return false; |
|
} |
|
if (tasks.length === 0) { |
|
callback(null); |
|
return false; |
|
} |
|
return true; |
|
} |
|
|
|
/** |
|
* check for waterfall tasks |
|
* @private |
|
* @param {function} func |
|
* @param {Array|Object} args - arguments |
|
* @return {function} next |
|
*/ |
|
function waterfallIterator(func, args, next) { |
|
switch (args.length) { |
|
case 0: |
|
case 1: |
|
return func(next); |
|
case 2: |
|
return func(args[1], next); |
|
case 3: |
|
return func(args[1], args[2], next); |
|
case 4: |
|
return func(args[1], args[2], args[3], next); |
|
case 5: |
|
return func(args[1], args[2], args[3], args[4], next); |
|
case 6: |
|
return func(args[1], args[2], args[3], args[4], args[5], next); |
|
default: |
|
args = slice(args, 1); |
|
args.push(next); |
|
return func.apply(null, args); |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace waterfall |
|
* @param {Array} tasks - functions |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* var order = []; |
|
* var tasks = [ |
|
* function(next) { |
|
* setTimeout(function() { |
|
* order.push(1); |
|
* next(null, 1); |
|
* }, 10); |
|
* }, |
|
* function(arg1, next) { |
|
* setTimeout(function() { |
|
* order.push(2); |
|
* next(null, 1, 2); |
|
* }, 30); |
|
* }, |
|
* function(arg1, arg2, next) { |
|
* setTimeout(function() { |
|
* order.push(3); |
|
* next(null, 3); |
|
* }, 20); |
|
* }, |
|
* function(arg1, next) { |
|
* setTimeout(function() { |
|
* order.push(4); |
|
* next(null, 1, 2, 3, 4); |
|
* }, 40); |
|
* } |
|
* ]; |
|
* async.waterfall(tasks, function(err, arg1, arg2, arg3, arg4) { |
|
* console.log(arg1, arg2, arg3, arg4); // 1 2 3 4 |
|
* }); |
|
* |
|
*/ |
|
function waterfall(tasks, callback) { |
|
callback = callback || noop; |
|
if (!checkWaterfallTasks(tasks, callback)) { |
|
return; |
|
} |
|
var func, args, done, sync; |
|
var completed = 0; |
|
var size = tasks.length; |
|
waterfallIterator(tasks[0], [], createCallback(0)); |
|
|
|
function iterate() { |
|
waterfallIterator(func, args, createCallback(func)); |
|
} |
|
|
|
function createCallback(index) { |
|
return function next(err, res) { |
|
if (index === undefined) { |
|
callback = noop; |
|
throwError(); |
|
} |
|
index = undefined; |
|
if (err) { |
|
done = callback; |
|
callback = throwError; |
|
done(err); |
|
return; |
|
} |
|
if (++completed === size) { |
|
done = callback; |
|
callback = throwError; |
|
if (arguments.length <= 2) { |
|
done(err, res); |
|
} else { |
|
done.apply(null, createArray(arguments)); |
|
} |
|
return; |
|
} |
|
if (sync) { |
|
args = arguments; |
|
func = tasks[completed] || throwError; |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
waterfallIterator(tasks[completed] || throwError, arguments, createCallback(completed)); |
|
} |
|
sync = false; |
|
}; |
|
} |
|
} |
|
|
|
/** |
|
* `angelFall` is like `waterfall` and inject callback to last argument of next task. |
|
* |
|
* @memberof async |
|
* @namespace angelFall |
|
* @param {Array} tasks - functions |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* var order = []; |
|
* var tasks = [ |
|
* function(next) { |
|
* setTimeout(function() { |
|
* order.push(1); |
|
* next(null, 1); |
|
* }, 10); |
|
* }, |
|
* function(arg1, empty, next) { |
|
* setTimeout(function() { |
|
* order.push(2); |
|
* next(null, 1, 2); |
|
* }, 30); |
|
* }, |
|
* function(next) { |
|
* setTimeout(function() { |
|
* order.push(3); |
|
* next(null, 3); |
|
* }, 20); |
|
* }, |
|
* function(arg1, empty1, empty2, empty3, next) { |
|
* setTimeout(function() { |
|
* order.push(4); |
|
* next(null, 1, 2, 3, 4); |
|
* }, 40); |
|
* } |
|
* ]; |
|
* async.angelFall(tasks, function(err, arg1, arg2, arg3, arg4) { |
|
* console.log(arg1, arg2, arg3, arg4); // 1 2 3 4 |
|
* }); |
|
* |
|
*/ |
|
function angelFall(tasks, callback) { |
|
callback = callback || noop; |
|
if (!checkWaterfallTasks(tasks, callback)) { |
|
return; |
|
} |
|
var completed = 0; |
|
var sync = false; |
|
var size = tasks.length; |
|
var func = tasks[completed]; |
|
var args = []; |
|
var iterate = function() { |
|
switch (func.length) { |
|
case 0: |
|
try { |
|
next(null, func()); |
|
} catch (e) { |
|
next(e); |
|
} |
|
return; |
|
case 1: |
|
return func(next); |
|
case 2: |
|
return func(args[1], next); |
|
case 3: |
|
return func(args[1], args[2], next); |
|
case 4: |
|
return func(args[1], args[2], args[3], next); |
|
case 5: |
|
return func(args[1], args[2], args[3], args[4], next); |
|
default: |
|
args = slice(args, 1); |
|
args[func.length - 1] = next; |
|
return func.apply(null, args); |
|
} |
|
}; |
|
iterate(); |
|
|
|
function next(err, res) { |
|
if (err) { |
|
iterate = throwError; |
|
callback = onlyOnce(callback); |
|
callback(err); |
|
return; |
|
} |
|
if (++completed === size) { |
|
iterate = throwError; |
|
var done = callback; |
|
callback = throwError; |
|
if (arguments.length === 2) { |
|
done(err, res); |
|
} else { |
|
done.apply(null, createArray(arguments)); |
|
} |
|
return; |
|
} |
|
func = tasks[completed]; |
|
args = arguments; |
|
if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace whilst |
|
* @param {Function} test |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
*/ |
|
function whilst(test, iterator, callback) { |
|
callback = callback || noop; |
|
var sync = false; |
|
if (test()) { |
|
iterate(); |
|
} else { |
|
callback(null); |
|
} |
|
|
|
function iterate() { |
|
if (sync) { |
|
nextTick(next); |
|
} else { |
|
sync = true; |
|
iterator(done); |
|
} |
|
sync = false; |
|
} |
|
|
|
function next() { |
|
iterator(done); |
|
} |
|
|
|
function done(err, arg) { |
|
if (err) { |
|
return callback(err); |
|
} |
|
if (arguments.length <= 2) { |
|
if (test(arg)) { |
|
iterate(); |
|
} else { |
|
callback(null, arg); |
|
} |
|
return; |
|
} |
|
arg = slice(arguments, 1); |
|
if (test.apply(null, arg)) { |
|
iterate(); |
|
} else { |
|
callback.apply(null, [null].concat(arg)); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace doWhilst |
|
* @param {Function} iterator |
|
* @param {Function} test |
|
* @param {Function} callback |
|
*/ |
|
function doWhilst(iterator, test, callback) { |
|
callback = callback || noop; |
|
var sync = false; |
|
next(); |
|
|
|
function iterate() { |
|
if (sync) { |
|
nextTick(next); |
|
} else { |
|
sync = true; |
|
iterator(done); |
|
} |
|
sync = false; |
|
} |
|
|
|
function next() { |
|
iterator(done); |
|
} |
|
|
|
function done(err, arg) { |
|
if (err) { |
|
return callback(err); |
|
} |
|
if (arguments.length <= 2) { |
|
if (test(arg)) { |
|
iterate(); |
|
} else { |
|
callback(null, arg); |
|
} |
|
return; |
|
} |
|
arg = slice(arguments, 1); |
|
if (test.apply(null, arg)) { |
|
iterate(); |
|
} else { |
|
callback.apply(null, [null].concat(arg)); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace until |
|
* @param {Function} test |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
*/ |
|
function until(test, iterator, callback) { |
|
callback = callback || noop; |
|
var sync = false; |
|
if (!test()) { |
|
iterate(); |
|
} else { |
|
callback(null); |
|
} |
|
|
|
function iterate() { |
|
if (sync) { |
|
nextTick(next); |
|
} else { |
|
sync = true; |
|
iterator(done); |
|
} |
|
sync = false; |
|
} |
|
|
|
function next() { |
|
iterator(done); |
|
} |
|
|
|
function done(err, arg) { |
|
if (err) { |
|
return callback(err); |
|
} |
|
if (arguments.length <= 2) { |
|
if (!test(arg)) { |
|
iterate(); |
|
} else { |
|
callback(null, arg); |
|
} |
|
return; |
|
} |
|
arg = slice(arguments, 1); |
|
if (!test.apply(null, arg)) { |
|
iterate(); |
|
} else { |
|
callback.apply(null, [null].concat(arg)); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace doUntil |
|
* @param {Function} iterator |
|
* @param {Function} test |
|
* @param {Function} callback |
|
*/ |
|
function doUntil(iterator, test, callback) { |
|
callback = callback || noop; |
|
var sync = false; |
|
next(); |
|
|
|
function iterate() { |
|
if (sync) { |
|
nextTick(next); |
|
} else { |
|
sync = true; |
|
iterator(done); |
|
} |
|
sync = false; |
|
} |
|
|
|
function next() { |
|
iterator(done); |
|
} |
|
|
|
function done(err, arg) { |
|
if (err) { |
|
return callback(err); |
|
} |
|
if (arguments.length <= 2) { |
|
if (!test(arg)) { |
|
iterate(); |
|
} else { |
|
callback(null, arg); |
|
} |
|
return; |
|
} |
|
arg = slice(arguments, 1); |
|
if (!test.apply(null, arg)) { |
|
iterate(); |
|
} else { |
|
callback.apply(null, [null].concat(arg)); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace during |
|
* @param {Function} test |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
*/ |
|
function during(test, iterator, callback) { |
|
callback = callback || noop; |
|
_test(); |
|
|
|
function _test() { |
|
test(iterate); |
|
} |
|
|
|
function iterate(err, truth) { |
|
if (err) { |
|
return callback(err); |
|
} |
|
if (truth) { |
|
iterator(done); |
|
} else { |
|
callback(null); |
|
} |
|
} |
|
|
|
function done(err) { |
|
if (err) { |
|
return callback(err); |
|
} |
|
_test(); |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace doDuring |
|
* @param {Function} test |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
*/ |
|
function doDuring(iterator, test, callback) { |
|
callback = callback || noop; |
|
iterate(null, true); |
|
|
|
function iterate(err, truth) { |
|
if (err) { |
|
return callback(err); |
|
} |
|
if (truth) { |
|
iterator(done); |
|
} else { |
|
callback(null); |
|
} |
|
} |
|
|
|
function done(err, res) { |
|
if (err) { |
|
return callback(err); |
|
} |
|
switch (arguments.length) { |
|
case 0: |
|
case 1: |
|
test(iterate); |
|
break; |
|
case 2: |
|
test(res, iterate); |
|
break; |
|
default: |
|
var args = slice(arguments, 1); |
|
args.push(iterate); |
|
test.apply(null, args); |
|
break; |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace forever |
|
*/ |
|
function forever(iterator, callback) { |
|
var sync = false; |
|
iterate(); |
|
|
|
function iterate() { |
|
iterator(next); |
|
} |
|
|
|
function next(err) { |
|
if (err) { |
|
if (callback) { |
|
return callback(err); |
|
} |
|
throw err; |
|
} |
|
if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace compose |
|
*/ |
|
function compose() { |
|
return seq.apply(null, reverse(arguments)); |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace seq |
|
*/ |
|
function seq(/* functions... */) { |
|
var fns = createArray(arguments); |
|
|
|
return function() { |
|
var self = this; |
|
var args = createArray(arguments); |
|
var callback = args[args.length - 1]; |
|
if (typeof callback === func) { |
|
args.pop(); |
|
} else { |
|
callback = noop; |
|
} |
|
reduce(fns, args, iterator, done); |
|
|
|
function iterator(newargs, fn, callback) { |
|
var func = function(err) { |
|
var nextargs = slice(arguments, 1); |
|
callback(err, nextargs); |
|
}; |
|
newargs.push(func); |
|
fn.apply(self, newargs); |
|
} |
|
|
|
function done(err, res) { |
|
res = isArray(res) ? res : [res]; |
|
res.unshift(err); |
|
callback.apply(self, res); |
|
} |
|
}; |
|
} |
|
|
|
function createApplyEach(func) { |
|
return function applyEach(fns /* arguments */) { |
|
var go = function() { |
|
var self = this; |
|
var args = createArray(arguments); |
|
var callback = args.pop() || noop; |
|
return func(fns, iterator, callback); |
|
|
|
function iterator(fn, done) { |
|
fn.apply(self, args.concat([done])); |
|
} |
|
}; |
|
if (arguments.length > 1) { |
|
var args = slice(arguments, 1); |
|
return go.apply(this, args); |
|
} else { |
|
return go; |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @see https://github.com/caolan/async/blob/master/lib/internal/DoublyLinkedList.js |
|
*/ |
|
function DLL() { |
|
this.head = null; |
|
this.tail = null; |
|
this.length = 0; |
|
} |
|
|
|
DLL.prototype._removeLink = function(node) { |
|
var prev = node.prev; |
|
var next = node.next; |
|
if (prev) { |
|
prev.next = next; |
|
} else { |
|
this.head = next; |
|
} |
|
if (next) { |
|
next.prev = prev; |
|
} else { |
|
this.tail = prev; |
|
} |
|
node.prev = null; |
|
node.next = null; |
|
this.length--; |
|
return node; |
|
}; |
|
|
|
DLL.prototype.empty = DLL; |
|
|
|
DLL.prototype._setInitial = function(node) { |
|
this.length = 1; |
|
this.head = this.tail = node; |
|
}; |
|
|
|
DLL.prototype.insertBefore = function(node, newNode) { |
|
newNode.prev = node.prev; |
|
newNode.next = node; |
|
if (node.prev) { |
|
node.prev.next = newNode; |
|
} else { |
|
this.head = newNode; |
|
} |
|
node.prev = newNode; |
|
this.length++; |
|
}; |
|
|
|
DLL.prototype.unshift = function(node) { |
|
if (this.head) { |
|
this.insertBefore(this.head, node); |
|
} else { |
|
this._setInitial(node); |
|
} |
|
}; |
|
|
|
DLL.prototype.push = function(node) { |
|
var tail = this.tail; |
|
if (tail) { |
|
node.prev = tail; |
|
node.next = tail.next; |
|
this.tail = node; |
|
tail.next = node; |
|
this.length++; |
|
} else { |
|
this._setInitial(node); |
|
} |
|
}; |
|
|
|
DLL.prototype.shift = function() { |
|
return this.head && this._removeLink(this.head); |
|
}; |
|
|
|
DLL.prototype.splice = function(end) { |
|
var task; |
|
var tasks = []; |
|
while (end-- && (task = this.shift())) { |
|
tasks.push(task); |
|
} |
|
return tasks; |
|
}; |
|
|
|
DLL.prototype.remove = function(test) { |
|
var node = this.head; |
|
while (node) { |
|
if (test(node)) { |
|
this._removeLink(node); |
|
} |
|
node = node.next; |
|
} |
|
return this; |
|
}; |
|
|
|
/** |
|
* @private |
|
*/ |
|
function baseQueue(isQueue, worker, concurrency, payload) { |
|
if (concurrency === undefined) { |
|
concurrency = 1; |
|
} else if (isNaN(concurrency) || concurrency < 1) { |
|
throw new Error('Concurrency must not be zero'); |
|
} |
|
|
|
var workers = 0; |
|
var workersList = []; |
|
var _callback, _unshift; |
|
|
|
var q = { |
|
_tasks: new DLL(), |
|
concurrency: concurrency, |
|
payload: payload, |
|
saturated: noop, |
|
unsaturated: noop, |
|
buffer: concurrency / 4, |
|
empty: noop, |
|
drain: noop, |
|
error: noop, |
|
started: false, |
|
paused: false, |
|
push: push, |
|
kill: kill, |
|
unshift: unshift, |
|
remove: remove, |
|
process: isQueue ? runQueue : runCargo, |
|
length: getLength, |
|
running: running, |
|
workersList: getWorkersList, |
|
idle: idle, |
|
pause: pause, |
|
resume: resume, |
|
_worker: worker |
|
}; |
|
return q; |
|
|
|
function push(tasks, callback) { |
|
_insert(tasks, callback); |
|
} |
|
|
|
function unshift(tasks, callback) { |
|
_insert(tasks, callback, true); |
|
} |
|
|
|
function _exec(task) { |
|
var item = { |
|
data: task, |
|
callback: _callback |
|
}; |
|
if (_unshift) { |
|
q._tasks.unshift(item); |
|
} else { |
|
q._tasks.push(item); |
|
} |
|
nextTick(q.process); |
|
} |
|
|
|
function _insert(tasks, callback, unshift) { |
|
if (callback == null) { |
|
callback = noop; |
|
} else if (typeof callback !== 'function') { |
|
throw new Error('task callback must be a function'); |
|
} |
|
q.started = true; |
|
var _tasks = isArray(tasks) ? tasks : [tasks]; |
|
|
|
if (tasks === undefined || !_tasks.length) { |
|
if (q.idle()) { |
|
nextTick(q.drain); |
|
} |
|
return; |
|
} |
|
|
|
_unshift = unshift; |
|
_callback = callback; |
|
arrayEachSync(_tasks, _exec); |
|
// Avoid leaking the callback |
|
_callback = undefined; |
|
} |
|
|
|
function kill() { |
|
q.drain = noop; |
|
q._tasks.empty(); |
|
} |
|
|
|
function _next(q, tasks) { |
|
var called = false; |
|
return function done(err, res) { |
|
if (called) { |
|
throwError(); |
|
} |
|
called = true; |
|
|
|
workers--; |
|
var task; |
|
var index = -1; |
|
var size = workersList.length; |
|
var taskIndex = -1; |
|
var taskSize = tasks.length; |
|
var useApply = arguments.length > 2; |
|
var args = useApply && createArray(arguments); |
|
while (++taskIndex < taskSize) { |
|
task = tasks[taskIndex]; |
|
while (++index < size) { |
|
if (workersList[index] === task) { |
|
if (index === 0) { |
|
workersList.shift(); |
|
} else { |
|
workersList.splice(index, 1); |
|
} |
|
index = size; |
|
size--; |
|
} |
|
} |
|
index = -1; |
|
if (useApply) { |
|
task.callback.apply(task, args); |
|
} else { |
|
task.callback(err, res); |
|
} |
|
if (err) { |
|
q.error(err, task.data); |
|
} |
|
} |
|
|
|
if (workers <= q.concurrency - q.buffer) { |
|
q.unsaturated(); |
|
} |
|
|
|
if (q._tasks.length + workers === 0) { |
|
q.drain(); |
|
} |
|
q.process(); |
|
}; |
|
} |
|
|
|
function runQueue() { |
|
while (!q.paused && workers < q.concurrency && q._tasks.length) { |
|
var task = q._tasks.shift(); |
|
workers++; |
|
workersList.push(task); |
|
if (q._tasks.length === 0) { |
|
q.empty(); |
|
} |
|
if (workers === q.concurrency) { |
|
q.saturated(); |
|
} |
|
var done = _next(q, [task]); |
|
worker(task.data, done); |
|
} |
|
} |
|
|
|
function runCargo() { |
|
while (!q.paused && workers < q.concurrency && q._tasks.length) { |
|
var tasks = q._tasks.splice(q.payload || q._tasks.length); |
|
var index = -1; |
|
var size = tasks.length; |
|
var data = Array(size); |
|
while (++index < size) { |
|
data[index] = tasks[index].data; |
|
} |
|
workers++; |
|
nativePush.apply(workersList, tasks); |
|
if (q._tasks.length === 0) { |
|
q.empty(); |
|
} |
|
if (workers === q.concurrency) { |
|
q.saturated(); |
|
} |
|
var done = _next(q, tasks); |
|
worker(data, done); |
|
} |
|
} |
|
|
|
function getLength() { |
|
return q._tasks.length; |
|
} |
|
|
|
function running() { |
|
return workers; |
|
} |
|
|
|
function getWorkersList() { |
|
return workersList; |
|
} |
|
|
|
function idle() { |
|
return q.length() + workers === 0; |
|
} |
|
|
|
function pause() { |
|
q.paused = true; |
|
} |
|
|
|
function _resume() { |
|
nextTick(q.process); |
|
} |
|
|
|
function resume() { |
|
if (q.paused === false) { |
|
return; |
|
} |
|
q.paused = false; |
|
var count = q.concurrency < q._tasks.length ? q.concurrency : q._tasks.length; |
|
timesSync(count, _resume); |
|
} |
|
|
|
/** |
|
* @param {Function} test |
|
*/ |
|
function remove(test) { |
|
q._tasks.remove(test); |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace queue |
|
*/ |
|
function queue(worker, concurrency) { |
|
return baseQueue(true, worker, concurrency); |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace priorityQueue |
|
*/ |
|
function priorityQueue(worker, concurrency) { |
|
var q = baseQueue(true, worker, concurrency); |
|
q.push = push; |
|
delete q.unshift; |
|
return q; |
|
|
|
function push(tasks, priority, callback) { |
|
q.started = true; |
|
priority = priority || 0; |
|
var _tasks = isArray(tasks) ? tasks : [tasks]; |
|
var taskSize = _tasks.length; |
|
|
|
if (tasks === undefined || taskSize === 0) { |
|
if (q.idle()) { |
|
nextTick(q.drain); |
|
} |
|
return; |
|
} |
|
|
|
callback = typeof callback === func ? callback : noop; |
|
var nextNode = q._tasks.head; |
|
while (nextNode && priority >= nextNode.priority) { |
|
nextNode = nextNode.next; |
|
} |
|
while (taskSize--) { |
|
var item = { |
|
data: _tasks[taskSize], |
|
priority: priority, |
|
callback: callback |
|
}; |
|
if (nextNode) { |
|
q._tasks.insertBefore(nextNode, item); |
|
} else { |
|
q._tasks.push(item); |
|
} |
|
nextTick(q.process); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace cargo |
|
*/ |
|
function cargo(worker, payload) { |
|
return baseQueue(false, worker, 1, payload); |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace auto |
|
* @param {Object} tasks |
|
* @param {number} [concurrency] |
|
* @param {Function} [callback] |
|
*/ |
|
function auto(tasks, concurrency, callback) { |
|
if (typeof concurrency === func) { |
|
callback = concurrency; |
|
concurrency = null; |
|
} |
|
var keys = nativeKeys(tasks); |
|
var rest = keys.length; |
|
var results = {}; |
|
if (rest === 0) { |
|
return callback(null, results); |
|
} |
|
var runningTasks = 0; |
|
var readyTasks = new DLL(); |
|
var listeners = Object.create(null); |
|
callback = onlyOnce(callback || noop); |
|
concurrency = concurrency || rest; |
|
|
|
baseEachSync(tasks, iterator, keys); |
|
proceedQueue(); |
|
|
|
function iterator(task, key) { |
|
// no dependencies |
|
var _task, _taskSize; |
|
if (!isArray(task)) { |
|
_task = task; |
|
_taskSize = 0; |
|
readyTasks.push([_task, _taskSize, done]); |
|
return; |
|
} |
|
var dependencySize = task.length - 1; |
|
_task = task[dependencySize]; |
|
_taskSize = dependencySize; |
|
if (dependencySize === 0) { |
|
readyTasks.push([_task, _taskSize, done]); |
|
return; |
|
} |
|
// dependencies |
|
var index = -1; |
|
while (++index < dependencySize) { |
|
var dependencyName = task[index]; |
|
if (notInclude(keys, dependencyName)) { |
|
var msg = |
|
'async.auto task `' + |
|
key + |
|
'` has non-existent dependency `' + |
|
dependencyName + |
|
'` in ' + |
|
task.join(', '); |
|
throw new Error(msg); |
|
} |
|
var taskListeners = listeners[dependencyName]; |
|
if (!taskListeners) { |
|
taskListeners = listeners[dependencyName] = []; |
|
} |
|
taskListeners.push(taskListener); |
|
} |
|
|
|
function done(err, arg) { |
|
if (key === null) { |
|
throwError(); |
|
} |
|
arg = arguments.length <= 2 ? arg : slice(arguments, 1); |
|
if (err) { |
|
rest = 0; |
|
runningTasks = 0; |
|
readyTasks.length = 0; |
|
var safeResults = objectClone(results); |
|
safeResults[key] = arg; |
|
key = null; |
|
var _callback = callback; |
|
callback = noop; |
|
_callback(err, safeResults); |
|
return; |
|
} |
|
runningTasks--; |
|
rest--; |
|
results[key] = arg; |
|
taskComplete(key); |
|
key = null; |
|
} |
|
|
|
function taskListener() { |
|
if (--dependencySize === 0) { |
|
readyTasks.push([_task, _taskSize, done]); |
|
} |
|
} |
|
} |
|
|
|
function proceedQueue() { |
|
if (readyTasks.length === 0 && runningTasks === 0) { |
|
if (rest !== 0) { |
|
throw new Error('async.auto task has cyclic dependencies'); |
|
} |
|
return callback(null, results); |
|
} |
|
while (readyTasks.length && runningTasks < concurrency && callback !== noop) { |
|
runningTasks++; |
|
var array = readyTasks.shift(); |
|
if (array[1] === 0) { |
|
array[0](array[2]); |
|
} else { |
|
array[0](results, array[2]); |
|
} |
|
} |
|
} |
|
|
|
function taskComplete(key) { |
|
var taskListeners = listeners[key] || []; |
|
arrayEachSync(taskListeners, function(task) { |
|
task(); |
|
}); |
|
proceedQueue(); |
|
} |
|
} |
|
|
|
var FN_ARGS = /^(function)?\s*[^\(]*\(\s*([^\)]*)\)/m; |
|
var FN_ARG_SPLIT = /,/; |
|
var FN_ARG = /(=.+)?(\s*)$/; |
|
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm; |
|
|
|
/** |
|
* parse function arguments for `autoInject` |
|
* |
|
* @private |
|
*/ |
|
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) { |
|
return arg.replace(FN_ARG, '').trim(); |
|
}); |
|
return func; |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace autoInject |
|
* @param {Object} tasks |
|
* @param {number} [concurrency] |
|
* @param {Function} [callback] |
|
*/ |
|
function autoInject(tasks, concurrency, callback) { |
|
var newTasks = {}; |
|
baseEachSync(tasks, iterator, nativeKeys(tasks)); |
|
auto(newTasks, concurrency, callback); |
|
|
|
function iterator(task, key) { |
|
var params; |
|
var taskLength = task.length; |
|
|
|
if (isArray(task)) { |
|
if (taskLength === 0) { |
|
throw new Error('autoInject task functions require explicit parameters.'); |
|
} |
|
params = createArray(task); |
|
taskLength = params.length - 1; |
|
task = params[taskLength]; |
|
if (taskLength === 0) { |
|
newTasks[key] = task; |
|
return; |
|
} |
|
} else if (taskLength === 1) { |
|
newTasks[key] = task; |
|
return; |
|
} else { |
|
params = parseParams(task); |
|
if (taskLength === 0 && params.length === 0) { |
|
throw new Error('autoInject task functions require explicit parameters.'); |
|
} |
|
taskLength = params.length - 1; |
|
} |
|
params[taskLength] = newTask; |
|
newTasks[key] = params; |
|
|
|
function newTask(results, done) { |
|
switch (taskLength) { |
|
case 1: |
|
task(results[params[0]], done); |
|
break; |
|
case 2: |
|
task(results[params[0]], results[params[1]], done); |
|
break; |
|
case 3: |
|
task(results[params[0]], results[params[1]], results[params[2]], done); |
|
break; |
|
default: |
|
var i = -1; |
|
while (++i < taskLength) { |
|
params[i] = results[params[i]]; |
|
} |
|
params[i] = done; |
|
task.apply(null, params); |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace retry |
|
* @param {integer|Object|Function} opts |
|
* @param {Function} [task] |
|
* @param {Function} [callback] |
|
*/ |
|
function retry(opts, task, callback) { |
|
var times, intervalFunc, errorFilter; |
|
var count = 0; |
|
if (arguments.length < 3 && typeof opts === func) { |
|
callback = task || noop; |
|
task = opts; |
|
opts = null; |
|
times = DEFAULT_TIMES; |
|
} else { |
|
callback = callback || noop; |
|
switch (typeof opts) { |
|
case 'object': |
|
if (typeof opts.errorFilter === func) { |
|
errorFilter = opts.errorFilter; |
|
} |
|
var interval = opts.interval; |
|
switch (typeof interval) { |
|
case func: |
|
intervalFunc = interval; |
|
break; |
|
case 'string': |
|
case 'number': |
|
interval = +interval; |
|
intervalFunc = interval |
|
? function() { |
|
return interval; |
|
} |
|
: function() { |
|
return DEFAULT_INTERVAL; |
|
}; |
|
break; |
|
} |
|
times = +opts.times || DEFAULT_TIMES; |
|
break; |
|
case 'number': |
|
times = opts || DEFAULT_TIMES; |
|
break; |
|
case 'string': |
|
times = +opts || DEFAULT_TIMES; |
|
break; |
|
default: |
|
throw new Error('Invalid arguments for async.retry'); |
|
} |
|
} |
|
if (typeof task !== 'function') { |
|
throw new Error('Invalid arguments for async.retry'); |
|
} |
|
|
|
if (intervalFunc) { |
|
task(intervalCallback); |
|
} else { |
|
task(simpleCallback); |
|
} |
|
|
|
function simpleIterator() { |
|
task(simpleCallback); |
|
} |
|
|
|
function simpleCallback(err, res) { |
|
if (++count === times || !err || (errorFilter && !errorFilter(err))) { |
|
if (arguments.length <= 2) { |
|
return callback(err, res); |
|
} |
|
var args = createArray(arguments); |
|
return callback.apply(null, args); |
|
} |
|
simpleIterator(); |
|
} |
|
|
|
function intervalIterator() { |
|
task(intervalCallback); |
|
} |
|
|
|
function intervalCallback(err, res) { |
|
if (++count === times || !err || (errorFilter && !errorFilter(err))) { |
|
if (arguments.length <= 2) { |
|
return callback(err, res); |
|
} |
|
var args = createArray(arguments); |
|
return callback.apply(null, args); |
|
} |
|
setTimeout(intervalIterator, intervalFunc(count)); |
|
} |
|
} |
|
|
|
function retryable(opts, task) { |
|
if (!task) { |
|
task = opts; |
|
opts = null; |
|
} |
|
return done; |
|
|
|
function done() { |
|
var taskFn; |
|
var args = createArray(arguments); |
|
var lastIndex = args.length - 1; |
|
var callback = args[lastIndex]; |
|
switch (task.length) { |
|
case 1: |
|
taskFn = task1; |
|
break; |
|
case 2: |
|
taskFn = task2; |
|
break; |
|
case 3: |
|
taskFn = task3; |
|
break; |
|
default: |
|
taskFn = task4; |
|
} |
|
if (opts) { |
|
retry(opts, taskFn, callback); |
|
} else { |
|
retry(taskFn, callback); |
|
} |
|
|
|
function task1(done) { |
|
task(done); |
|
} |
|
|
|
function task2(done) { |
|
task(args[0], done); |
|
} |
|
|
|
function task3(done) { |
|
task(args[0], args[1], done); |
|
} |
|
|
|
function task4(callback) { |
|
args[lastIndex] = callback; |
|
task.apply(null, args); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace iterator |
|
*/ |
|
function iterator(tasks) { |
|
var size = 0; |
|
var keys = []; |
|
if (isArray(tasks)) { |
|
size = tasks.length; |
|
} else { |
|
keys = nativeKeys(tasks); |
|
size = keys.length; |
|
} |
|
return makeCallback(0); |
|
|
|
function makeCallback(index) { |
|
var fn = function() { |
|
if (size) { |
|
var key = keys[index] || index; |
|
tasks[key].apply(null, createArray(arguments)); |
|
} |
|
return fn.next(); |
|
}; |
|
fn.next = function() { |
|
return index < size - 1 ? makeCallback(index + 1) : null; |
|
}; |
|
return fn; |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace apply |
|
*/ |
|
function apply(func) { |
|
switch (arguments.length) { |
|
case 0: |
|
case 1: |
|
return func; |
|
case 2: |
|
return func.bind(null, arguments[1]); |
|
case 3: |
|
return func.bind(null, arguments[1], arguments[2]); |
|
case 4: |
|
return func.bind(null, arguments[1], arguments[2], arguments[3]); |
|
case 5: |
|
return func.bind(null, arguments[1], arguments[2], arguments[3], arguments[4]); |
|
default: |
|
var size = arguments.length; |
|
var index = 0; |
|
var args = Array(size); |
|
args[index] = null; |
|
while (++index < size) { |
|
args[index] = arguments[index]; |
|
} |
|
return func.bind.apply(func, args); |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace timeout |
|
* @param {Function} func |
|
* @param {number} millisec |
|
* @param {*} info |
|
*/ |
|
function timeout(func, millisec, info) { |
|
var callback, timer; |
|
return wrappedFunc; |
|
|
|
function wrappedFunc() { |
|
timer = setTimeout(timeoutCallback, millisec); |
|
var args = createArray(arguments); |
|
var lastIndex = args.length - 1; |
|
callback = args[lastIndex]; |
|
args[lastIndex] = injectedCallback; |
|
simpleApply(func, args); |
|
} |
|
|
|
function timeoutCallback() { |
|
var name = func.name || 'anonymous'; |
|
var err = new Error('Callback function "' + name + '" timed out.'); |
|
err.code = 'ETIMEDOUT'; |
|
if (info) { |
|
err.info = info; |
|
} |
|
timer = null; |
|
callback(err); |
|
} |
|
|
|
function injectedCallback() { |
|
if (timer !== null) { |
|
simpleApply(callback, createArray(arguments)); |
|
clearTimeout(timer); |
|
} |
|
} |
|
|
|
function simpleApply(func, args) { |
|
switch (args.length) { |
|
case 0: |
|
func(); |
|
break; |
|
case 1: |
|
func(args[0]); |
|
break; |
|
case 2: |
|
func(args[0], args[1]); |
|
break; |
|
default: |
|
func.apply(null, args); |
|
break; |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace times |
|
* @param {number} n - n >= 1 |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* var iterator = function(n, done) { |
|
* done(null, n); |
|
* }; |
|
* async.times(4, iterator, function(err, res) { |
|
* console.log(res); // [0, 1, 2, 3]; |
|
* }); |
|
* |
|
*/ |
|
function times(n, iterator, callback) { |
|
callback = callback || noop; |
|
n = +n; |
|
if (isNaN(n) || n < 1) { |
|
return callback(null, []); |
|
} |
|
var result = Array(n); |
|
timesSync(n, iterate); |
|
|
|
function iterate(num) { |
|
iterator(num, createCallback(num)); |
|
} |
|
|
|
function createCallback(index) { |
|
return function(err, res) { |
|
if (index === null) { |
|
throwError(); |
|
} |
|
result[index] = res; |
|
index = null; |
|
if (err) { |
|
callback(err); |
|
callback = noop; |
|
} else if (--n === 0) { |
|
callback(null, result); |
|
} |
|
}; |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace timesSeries |
|
* @param {number} n - n >= 1 |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* var iterator = function(n, done) { |
|
* done(null, n); |
|
* }; |
|
* async.timesSeries(4, iterator, function(err, res) { |
|
* console.log(res); // [0, 1, 2, 3]; |
|
* }); |
|
* |
|
*/ |
|
function timesSeries(n, iterator, callback) { |
|
callback = callback || noop; |
|
n = +n; |
|
if (isNaN(n) || n < 1) { |
|
return callback(null, []); |
|
} |
|
var result = Array(n); |
|
var sync = false; |
|
var completed = 0; |
|
iterate(); |
|
|
|
function iterate() { |
|
iterator(completed, done); |
|
} |
|
|
|
function done(err, res) { |
|
result[completed] = res; |
|
if (err) { |
|
callback(err); |
|
callback = throwError; |
|
} else if (++completed >= n) { |
|
callback(null, result); |
|
callback = throwError; |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace timesLimit |
|
* @param {number} n - n >= 1 |
|
* @param {number} limit - n >= 1 |
|
* @param {Function} iterator |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* var iterator = function(n, done) { |
|
* done(null, n); |
|
* }; |
|
* async.timesLimit(4, 2, iterator, function(err, res) { |
|
* console.log(res); // [0, 1, 2, 3]; |
|
* }); |
|
* |
|
*/ |
|
function timesLimit(n, limit, iterator, callback) { |
|
callback = callback || noop; |
|
n = +n; |
|
if (isNaN(n) || n < 1 || isNaN(limit) || limit < 1) { |
|
return callback(null, []); |
|
} |
|
var result = Array(n); |
|
var sync = false; |
|
var started = 0; |
|
var completed = 0; |
|
timesSync(limit > n ? n : limit, iterate); |
|
|
|
function iterate() { |
|
var index = started++; |
|
if (index < n) { |
|
iterator(index, createCallback(index)); |
|
} |
|
} |
|
|
|
function createCallback(index) { |
|
return function(err, res) { |
|
if (index === null) { |
|
throwError(); |
|
} |
|
result[index] = res; |
|
index = null; |
|
if (err) { |
|
callback(err); |
|
callback = noop; |
|
} else if (++completed >= n) { |
|
callback(null, result); |
|
callback = throwError; |
|
} else if (sync) { |
|
nextTick(iterate); |
|
} else { |
|
sync = true; |
|
iterate(); |
|
} |
|
sync = false; |
|
}; |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace race |
|
* @param {Array|Object} tasks - functions |
|
* @param {Function} callback |
|
* @example |
|
* |
|
* // array |
|
* var called = 0; |
|
* var tasks = [ |
|
* function(done) { |
|
* setTimeout(function() { |
|
* called++; |
|
* done(null, '1'); |
|
* }, 30); |
|
* }, |
|
* function(done) { |
|
* setTimeout(function() { |
|
* called++; |
|
* done(null, '2'); |
|
* }, 20); |
|
* }, |
|
* function(done) { |
|
* setTimeout(function() { |
|
* called++; |
|
* done(null, '3'); |
|
* }, 10); |
|
* } |
|
* ]; |
|
* async.race(tasks, function(err, res) { |
|
* console.log(res); // '3' |
|
* console.log(called); // 1 |
|
* setTimeout(function() { |
|
* console.log(called); // 3 |
|
* }, 50); |
|
* }); |
|
* |
|
* @example |
|
* |
|
* // object |
|
* var called = 0; |
|
* var tasks = { |
|
* 'test1': function(done) { |
|
* setTimeout(function() { |
|
* called++; |
|
* done(null, '1'); |
|
* }, 30); |
|
* }, |
|
* 'test2': function(done) { |
|
* setTimeout(function() { |
|
* called++; |
|
* done(null, '2'); |
|
* }, 20); |
|
* }, |
|
* 'test3': function(done) { |
|
* setTimeout(function() { |
|
* called++; |
|
* done(null, '3'); |
|
* }, 10); |
|
* } |
|
* }; |
|
* async.race(tasks, function(err, res) { |
|
* console.log(res); // '3' |
|
* console.log(called); // 1 |
|
* setTimeout(function() { |
|
* console.log(called); // 3 |
|
* done(); |
|
* }, 50); |
|
* }); |
|
* |
|
*/ |
|
function race(tasks, callback) { |
|
callback = once(callback || noop); |
|
var size, keys; |
|
var index = -1; |
|
if (isArray(tasks)) { |
|
size = tasks.length; |
|
while (++index < size) { |
|
tasks[index](callback); |
|
} |
|
} else if (tasks && typeof tasks === obj) { |
|
keys = nativeKeys(tasks); |
|
size = keys.length; |
|
while (++index < size) { |
|
tasks[keys[index]](callback); |
|
} |
|
} else { |
|
return callback(new TypeError('First argument to race must be a collection of functions')); |
|
} |
|
if (!size) { |
|
callback(null); |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace memoize |
|
*/ |
|
function memoize(fn, hasher) { |
|
hasher = |
|
hasher || |
|
function(hash) { |
|
return hash; |
|
}; |
|
|
|
var memo = {}; |
|
var queues = {}; |
|
var memoized = function() { |
|
var args = createArray(arguments); |
|
var callback = args.pop(); |
|
var key = hasher.apply(null, args); |
|
if (has(memo, key)) { |
|
nextTick(function() { |
|
callback.apply(null, memo[key]); |
|
}); |
|
return; |
|
} |
|
if (has(queues, key)) { |
|
return queues[key].push(callback); |
|
} |
|
|
|
queues[key] = [callback]; |
|
args.push(done); |
|
fn.apply(null, args); |
|
|
|
function done(err) { |
|
var args = createArray(arguments); |
|
if (!err) { |
|
memo[key] = args; |
|
} |
|
var q = queues[key]; |
|
delete queues[key]; |
|
|
|
var i = -1; |
|
var size = q.length; |
|
while (++i < size) { |
|
q[i].apply(null, args); |
|
} |
|
} |
|
}; |
|
memoized.memo = memo; |
|
memoized.unmemoized = fn; |
|
return memoized; |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace unmemoize |
|
*/ |
|
function unmemoize(fn) { |
|
return function() { |
|
return (fn.unmemoized || fn).apply(null, arguments); |
|
}; |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace ensureAsync |
|
*/ |
|
function ensureAsync(fn) { |
|
return function(/* ...args, callback */) { |
|
var args = createArray(arguments); |
|
var lastIndex = args.length - 1; |
|
var callback = args[lastIndex]; |
|
var sync = true; |
|
args[lastIndex] = done; |
|
fn.apply(this, args); |
|
sync = false; |
|
|
|
function done() { |
|
var innerArgs = createArray(arguments); |
|
if (sync) { |
|
nextTick(function() { |
|
callback.apply(null, innerArgs); |
|
}); |
|
} else { |
|
callback.apply(null, innerArgs); |
|
} |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace constant |
|
*/ |
|
function constant(/* values... */) { |
|
var args = [null].concat(createArray(arguments)); |
|
return function(callback) { |
|
callback = arguments[arguments.length - 1]; |
|
callback.apply(this, args); |
|
}; |
|
} |
|
|
|
function asyncify(fn) { |
|
return function(/* args..., callback */) { |
|
var args = createArray(arguments); |
|
var callback = args.pop(); |
|
var result; |
|
try { |
|
result = fn.apply(this, args); |
|
} catch (e) { |
|
return callback(e); |
|
} |
|
if (result && typeof result.then === func) { |
|
result.then( |
|
function(value) { |
|
invokeCallback(callback, null, value); |
|
}, |
|
function(err) { |
|
invokeCallback(callback, err && err.message ? err : new Error(err)); |
|
} |
|
); |
|
} else { |
|
callback(null, result); |
|
} |
|
}; |
|
} |
|
|
|
function invokeCallback(callback, err, value) { |
|
try { |
|
callback(err, value); |
|
} catch (e) { |
|
nextTick(rethrow, e); |
|
} |
|
} |
|
|
|
function rethrow(error) { |
|
throw error; |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace reflect |
|
* @param {Function} func |
|
* @return {Function} |
|
*/ |
|
function reflect(func) { |
|
return function(/* args..., callback */) { |
|
var callback; |
|
switch (arguments.length) { |
|
case 1: |
|
callback = arguments[0]; |
|
return func(done); |
|
case 2: |
|
callback = arguments[1]; |
|
return func(arguments[0], done); |
|
default: |
|
var args = createArray(arguments); |
|
var lastIndex = args.length - 1; |
|
callback = args[lastIndex]; |
|
args[lastIndex] = done; |
|
func.apply(this, args); |
|
} |
|
|
|
function done(err, res) { |
|
if (err) { |
|
return callback(null, { |
|
error: err |
|
}); |
|
} |
|
if (arguments.length > 2) { |
|
res = slice(arguments, 1); |
|
} |
|
callback(null, { |
|
value: res |
|
}); |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace reflectAll |
|
* @param {Array[]|Object} tasks |
|
* @return {Function} |
|
*/ |
|
function reflectAll(tasks) { |
|
var newTasks, keys; |
|
if (isArray(tasks)) { |
|
newTasks = Array(tasks.length); |
|
arrayEachSync(tasks, iterate); |
|
} else if (tasks && typeof tasks === obj) { |
|
keys = nativeKeys(tasks); |
|
newTasks = {}; |
|
baseEachSync(tasks, iterate, keys); |
|
} |
|
return newTasks; |
|
|
|
function iterate(func, key) { |
|
newTasks[key] = reflect(func); |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace createLogger |
|
*/ |
|
function createLogger(name) { |
|
return function(fn) { |
|
var args = slice(arguments, 1); |
|
args.push(done); |
|
fn.apply(null, args); |
|
}; |
|
|
|
function done(err) { |
|
if (typeof console === obj) { |
|
if (err) { |
|
if (console.error) { |
|
console.error(err); |
|
} |
|
return; |
|
} |
|
if (console[name]) { |
|
var args = slice(arguments, 1); |
|
arrayEachSync(args, function(arg) { |
|
console[name](arg); |
|
}); |
|
} |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace safe |
|
*/ |
|
function safe() { |
|
createImmediate(); |
|
return exports; |
|
} |
|
|
|
/** |
|
* @memberof async |
|
* @namespace fast |
|
*/ |
|
function fast() { |
|
createImmediate(false); |
|
return exports; |
|
} |
|
});
|
|
|