Comparing version 1.5.0 to 2.0.0
1042
lib/index.js
@@ -1,627 +0,319 @@ | ||
var async = require('neo-async'); | ||
var regAsync = require('async'); | ||
var Promise = require('es6-promise').Promise; | ||
const pLimit = require('p-limit'); | ||
function throwIteratorMisuseError() { | ||
throw new Error('Do not call the callback when using pasync. Return a promise instead.'); | ||
} | ||
// Used as a placeholder if a promise is rejected without a reason | ||
var placeholderError = new Error('An error occurred inside pasync'); | ||
function processResultError(err) { | ||
if(err === placeholderError) return undefined; | ||
return err; | ||
let tickFn; | ||
if (typeof process === 'object' && typeof process.nextTick === 'function') { | ||
tickFn = process.nextTick; | ||
} else if (typeof setImmediate === 'function') { | ||
tickFn = setImmediate; | ||
} else { | ||
tickFn = function(fn) { | ||
setTimeout(fn, 0); | ||
} | ||
} | ||
/** | ||
* Constructs a replacement iterator function that wraps a | ||
* promise-based function. | ||
* | ||
* @param {Function} promiseIterator - The given promise-based iterator function | ||
* @param {Number} iteratorCallbackPos - The position of the callback in the iterator argument list, if <0, tries to autodetect | ||
* @param {Boolean} iteratorProvidesValue - If true, the iterator provides the promise resolve value as a callback argument | ||
* @param {Boolean} noErrors - If true, the iterator callback does not accept an initial error argument | ||
* @param {Function} unhandledErrorHandler - A function to be called if an error occurs when noErrors is set | ||
* @return {Function} - The wrapper function | ||
*/ | ||
function constructIterator(promiseIterator, iteratorCallbackPos, iteratorProvidesValue, noErrors, unhandledErrorHandler) { | ||
return function() { | ||
var args = Array.prototype.slice.call(arguments, 0); | ||
var handleError = function(err) { | ||
if(!err) { | ||
err = placeholderError; | ||
function breakoutFunctionArguments(funcArgs, argsOptions = {}) { | ||
let ret = { opArgs: [] }; | ||
if (argsOptions.opIndexes) { | ||
for (let index of argsOptions.opIndexes) { | ||
if (index > funcArgs.length) { | ||
throw new Error('Not enough arguments to pasync function'); | ||
} | ||
if(noErrors) { | ||
unhandledErrorHandler(err); | ||
iteratorCallback(); | ||
} else { | ||
iteratorCallback(err); | ||
} | ||
}; | ||
var iteratorCallback; | ||
if(iteratorCallbackPos >= 0) { | ||
iteratorCallback = args[iteratorCallbackPos]; | ||
} else { | ||
for(var i = 0; i < args.length; i++) { | ||
if(typeof args[i] === 'function') { | ||
iteratorCallback = args[i]; | ||
} | ||
} | ||
ret.opArgs.push(funcArgs[index]); | ||
} | ||
// Install a function in the iterator callback's place to avoid accidental misuse | ||
args[iteratorCallbackPos] = throwIteratorMisuseError; | ||
// iteratorResult can either be a promise or a value | ||
var iteratorResult; | ||
try { | ||
iteratorResult = promiseIterator.apply(this, args); | ||
} catch (ex) { | ||
// Treat exceptions as promise rejections | ||
setImmediate(function() { | ||
handleError(ex); | ||
}); | ||
return; | ||
} else { | ||
ret.opArgs.push(...funcArgs); | ||
} | ||
if (argsOptions.limitIndex) { | ||
if (argsOptions.limitIndex > funcArgs.length) { | ||
throw new Error('Not enough arguments to pasync function'); | ||
} | ||
if(iteratorResult && typeof iteratorResult.then === 'function') { | ||
iteratorResult.then(function(value) { | ||
if(iteratorProvidesValue) { | ||
if(noErrors) { | ||
iteratorCallback(value); | ||
} else { | ||
iteratorCallback(null, value); | ||
} | ||
} else { | ||
iteratorCallback(); | ||
} | ||
}, function(err) { | ||
handleError(err); | ||
}).then(undefined, function(err) { | ||
// Throw error in global | ||
setImmediate(function() { | ||
throw err; | ||
}); | ||
}); | ||
} else { | ||
setImmediate(function() { | ||
if(iteratorProvidesValue) { | ||
if(noErrors) { | ||
iteratorCallback(iteratorResult); | ||
} else { | ||
iteratorCallback(null, iteratorResult); | ||
} | ||
} else { | ||
iteratorCallback(); | ||
} | ||
}); | ||
} | ||
}; | ||
ret.limit = funcArgs[argsOptions.limitIndex]; | ||
} | ||
return ret; | ||
} | ||
/** | ||
* Given an async library function that involves an iterator and a | ||
* callback on completion, returns a promisified version. | ||
* | ||
* @param {Function} fn - The async library function | ||
* @param {Number} iteratorPos - The index of the iterator in the arguments array | ||
* @param {Number} iteratorCallbackPos - The index of the 'next' callback in the iterator's arguments | ||
* @param {Number} callbackPos - The index of the completion callback in the arguments array | ||
* @param {Boolean} iteratorProvidesValue - True if the iterator's callback accepts a second (value) argument | ||
* @param {Boolean} noErrors - True if the iterator does not receive an error to its callback and | ||
* the finish callback does not receive an error | ||
* @return {Function} | ||
*/ | ||
function convertIteratorFunction(fn, iteratorPos, iteratorCallbackPos, callbackPos, iteratorProvidesValue, noErrors) { | ||
if(typeof fn !== 'function') return fn; | ||
// Wrappers for async collections that operate in parallel, series, or limit | ||
function wrapParallel(opsFunc, argsOptions) { | ||
return async function() { | ||
let { opArgs } = breakoutFunctionArguments(Array.prototype.slice.call(arguments), argsOptions); | ||
let context = {}; | ||
await Promise.all(opsFunc(context, ...opArgs) | ||
.map((func) => func())); | ||
return function() { | ||
var promiseIterator = arguments[iteratorPos]; | ||
if(arguments[callbackPos] !== undefined) { | ||
throw new Error('Do not supply a callback when using psaync. This function returns a promise.'); | ||
} | ||
// Some async functions (such as filter) do not handle errors. | ||
// In these cases, we handle errors out-of-band. | ||
var firstUnhandledError; | ||
var newIterator = constructIterator(promiseIterator, iteratorCallbackPos, iteratorProvidesValue, noErrors, function(err) { | ||
firstUnhandledError = err; | ||
}); | ||
var fnArgs = arguments; | ||
return new Promise(function(resolve, reject) { | ||
fnArgs[callbackPos] = function(err, value) { | ||
if(firstUnhandledError) { | ||
reject(processResultError(firstUnhandledError)); | ||
} else if(noErrors) { | ||
resolve(err); | ||
} else if(err) { | ||
reject(processResultError(err)); | ||
} else { | ||
resolve(value); | ||
} | ||
}; | ||
if(callbackPos >= fnArgs.length) fnArgs.length = callbackPos + 1; | ||
fnArgs[iteratorPos] = newIterator; | ||
fn.apply(async, fnArgs); | ||
}); | ||
if (typeof context.ret === 'function') return context.ret(); | ||
if (context.ret !== undefined) return context.ret; | ||
}; | ||
} | ||
function convertTaskFunction(fn, iteratorPos, iteratorCallbackPos, callbackPos, iteratorProvidesValue) { | ||
if(typeof fn !== 'function') return fn; | ||
return function() { | ||
if(arguments[callbackPos] !== undefined) { | ||
throw new Error('Do not supply a callback when using psaync. This function returns a promise.'); | ||
function wrapSeries(opsFunc, argsOptions) { | ||
return async function() { | ||
let { opArgs } = breakoutFunctionArguments(Array.prototype.slice.call(arguments), argsOptions); | ||
let context = {}; | ||
let ops = opsFunc(context, ...opArgs); | ||
for (let op of ops) { | ||
await op(); | ||
} | ||
var newIterator; | ||
if(Array.isArray(arguments[iteratorPos])) { | ||
newIterator = arguments[iteratorPos].map(function(iterator) { | ||
return constructIterator(iterator, iteratorCallbackPos, iteratorProvidesValue); | ||
}); | ||
} else if(typeof arguments[iteratorPos] === 'object') { | ||
var obj = arguments[iteratorPos]; | ||
Object.keys(obj).forEach(function(iterator) { | ||
obj[iterator] = constructIterator(obj[iterator], iteratorCallbackPos, iteratorProvidesValue); | ||
}); | ||
newIterator = obj; | ||
} else { | ||
newIterator = constructIterator(arguments[iteratorPos], iteratorCallbackPos, iteratorProvidesValue); | ||
} | ||
var fnArgs = arguments; | ||
return new Promise(function(resolve, reject) { | ||
fnArgs[callbackPos] = function(err, value) { | ||
if(err) { | ||
reject(processResultError(err)); | ||
} else { | ||
resolve(value); | ||
} | ||
}; | ||
if(callbackPos >= fnArgs.length) fnArgs.length = callbackPos + 1; | ||
fnArgs[iteratorPos] = newIterator; | ||
fn.apply(async, fnArgs); | ||
}); | ||
if (typeof context.ret === 'function') return context.ret(); | ||
if (context.ret !== undefined) return context.ret; | ||
}; | ||
} | ||
// Iterator functions | ||
function wrapLimit(opsFunc, argsOptions) { | ||
return async function() { | ||
let { opArgs, limit } = breakoutFunctionArguments(Array.prototype.slice.call(arguments), argsOptions); | ||
let context = {}; | ||
let limiter = pLimit(limit); | ||
let ops = opsFunc(context, ...opArgs) | ||
.map((op) => limiter(() => op())); | ||
await Promise.all(ops); | ||
if (typeof context.ret === 'function') return context.ret(); | ||
if (context.ret !== undefined) return context.ret; | ||
} | ||
} | ||
// fn, iteratorPos, iteratorCallbackPos, callbackPos, iteratorProvidesValue, noErrors | ||
exports.each = convertIteratorFunction(async.each, 1, 1, 2, false, false); | ||
exports.eachSeries = convertIteratorFunction(async.eachSeries, 1, 1, 2, false, false); | ||
exports.eachLimit = convertIteratorFunction(async.eachLimit, 2, 1, 3, false, false); | ||
exports.map = convertIteratorFunction(async.map, 1, 1, 2, true, false); | ||
exports.mapSeries = convertIteratorFunction(async.mapSeries, 1, 1, 2, true, false); | ||
exports.mapLimit = convertIteratorFunction(async.mapLimit, 2, 1, 3, true, false); | ||
exports.filter = convertIteratorFunction(async.filter, 1, 1, 2, true, true); | ||
exports.select = exports.filter; | ||
exports.filterSeries = convertIteratorFunction(async.filterSeries, 1, 1, 2, true, true); | ||
exports.selectSeries = exports.filterSeries; | ||
exports.reject = convertIteratorFunction(async.reject, 1, 1, 2, true, true); | ||
exports.rejectSeries = convertIteratorFunction(async.rejectSeries, 1, 1, 2, true, true); | ||
exports.reduce = convertIteratorFunction(async.reduce, 2, 2, 3, true, false); | ||
exports.inject = exports.reduce; | ||
exports.foldl = exports.reduce; | ||
exports.reduceRight = convertIteratorFunction(async.reduceRight, 2, 2, 3, true, false); | ||
exports.foldr = exports.reduceRight; | ||
exports.detect = convertIteratorFunction(async.detect, 1, 1, 2, true, true); | ||
exports.detectSeries = convertIteratorFunction(async.detectSeries, 1, 1, 2, true, true); | ||
exports.sortBy = convertIteratorFunction(async.sortBy, 1, 1, 2, true, false); | ||
exports.some = convertIteratorFunction(async.some, 1, 1, 2, true, true); | ||
exports.every = convertIteratorFunction(async.every, 1, 1, 2, true, true); | ||
exports.concat = convertIteratorFunction(async.concat, 1, 1, 2, true, false); | ||
exports.concatSeries = convertIteratorFunction(async.concatSeries, 1, 1, 2, true, false); | ||
// Processors for each async collection | ||
// Each op function returns an array of promise-returning functions to execute | ||
// Task functions | ||
exports.series = convertTaskFunction(async.series, 0, 0, 1, true); | ||
exports.parallel = convertTaskFunction(async.parallel, 0, 0, 1, true); | ||
exports.parallelLimit = convertTaskFunction(async.parallelLimit, 0, 0, 2, true); | ||
exports.whilst = convertTaskFunction(async.whilst, 1, 0, 2, false); | ||
exports.doWhilst = convertTaskFunction(async.doWhilst, 0, 0, 2, false); | ||
exports.until = convertTaskFunction(async.until, 1, 0, 2, false); | ||
exports.doUntil = convertTaskFunction(async.doUntil, 0, 0, 2, false); | ||
exports.forever = convertTaskFunction(async.forever, 0, 0, 1, false); | ||
// Note: waterfall with promises does not support multiple result args | ||
exports.waterfall = convertTaskFunction(async.waterfall, 0, -1, 1, true); | ||
function eachOps(context, values, iter) { | ||
if (typeof values === 'object' && !Array.isArray(values)) { | ||
values = Object.values(values); | ||
} | ||
return values.map(function(value) { | ||
return async function() { | ||
await iter(value); | ||
}; | ||
}); | ||
} | ||
// Misc Functions | ||
function mapOps(context, values, iter) { | ||
if (typeof values === 'object' && !Array.isArray(values)) { | ||
values = Object.values(values); | ||
} | ||
context.ret = new Array(values.length); | ||
return values.map(function(value, index) { | ||
return async function() { | ||
let retValue = await iter(value); | ||
context.ret[index] = retValue; | ||
}; | ||
}); | ||
} | ||
exports.compose = function() { | ||
var promiseFns = Array.prototype.slice.call(arguments, 0); | ||
var callbackFns = promiseFns.map(function(promiseFn) { | ||
return constructIterator(promiseFn, 1, true, false); | ||
function mapValuesOps(context, values, iter) { | ||
let destructuredValues = []; | ||
if (Array.isArray(values)) { | ||
context.ret = new Array(values.length); | ||
for (let i = 0; i < values.length; i++) { | ||
destructuredValues.push({ key: i, value: values[i] }); | ||
} | ||
} else { | ||
context.ret = {}; | ||
for (let key in values) { | ||
destructuredValues.push({ key: key, value: values[key] }); | ||
} | ||
} | ||
return destructuredValues.map(function(valueObj) { | ||
return async function() { | ||
let retValue = await iter(valueObj.value); | ||
context.ret[valueObj.key] = retValue; | ||
}; | ||
}); | ||
var resultCallbackFn = async.compose.apply(async, callbackFns); | ||
return function(arg) { | ||
var self = this; | ||
return new Promise(function(resolve, reject) { | ||
resultCallbackFn.call(self, arg, function(err, result) { | ||
if(err) { | ||
reject(err); | ||
} else { | ||
resolve(result); | ||
} | ||
}); | ||
}); | ||
}; | ||
}; | ||
} | ||
exports.seq = function() { | ||
var promiseFns = Array.prototype.slice.call(arguments, 0); | ||
promiseFns.reverse(); | ||
return exports.compose.apply(exports, promiseFns); | ||
}; | ||
exports.applyEach = function() { | ||
var promiseFns = arguments[0]; | ||
var callback = arguments[arguments.length - 1]; | ||
var fnArgs = Array.prototype.slice.call(arguments, 1); | ||
var callbackFns = promiseFns.map(function(promiseFn) { | ||
return constructIterator(promiseFn, fnArgs.length, false, false); | ||
}); | ||
return new Promise(function(resolve, reject) { | ||
async.applyEach.apply(async, [callbackFns].concat(fnArgs).concat([function(err) { | ||
if(err) { | ||
reject(err); | ||
function filterOps(context, values, iter) { | ||
context.unfilteredRet = new Array(values.length); | ||
context.ret = function() { | ||
return this.unfilteredRet.filter((elem) => (elem !== undefined)); | ||
} | ||
return values.map(function(value, index) { | ||
return async function() { | ||
let shouldAccept = await iter(value); | ||
if (shouldAccept) { | ||
context.unfilteredRet[index] = value; | ||
} else { | ||
resolve(); | ||
context.unfilteredRet[index] = undefined; | ||
} | ||
}])); | ||
}; | ||
}); | ||
}; | ||
} | ||
exports.applyEachSeries = function() { | ||
var promiseFns = arguments[0]; | ||
var callback = arguments[arguments.length - 1]; | ||
var fnArgs = Array.prototype.slice.call(arguments, 1); | ||
var callbackFns = promiseFns.map(function(promiseFn) { | ||
return constructIterator(promiseFn, fnArgs.length, false, false); | ||
}); | ||
return new Promise(function(resolve, reject) { | ||
async.applyEachSeries.apply(async, [callbackFns].concat(fnArgs).concat([function(err) { | ||
if(err) { | ||
reject(err); | ||
function rejectOps(context, values, iter) { | ||
context.unfilteredRet = new Array(values.length); | ||
context.ret = function() { | ||
return this.unfilteredRet.filter((elem) => (elem !== undefined)); | ||
} | ||
return values.map(function(value, index) { | ||
return async function() { | ||
let shouldReject = await iter(value); | ||
if (!shouldReject) { | ||
context.unfilteredRet[index] = value; | ||
} else { | ||
resolve(); | ||
context.unfilteredRet[index] = undefined; | ||
} | ||
}])); | ||
}; | ||
}); | ||
}; | ||
} | ||
exports.queue = function(promiseWorker, concurrency) { | ||
var callbackWorker = constructIterator(promiseWorker, 1, false, false); | ||
var queue = async.queue(callbackWorker, concurrency); | ||
var origPush = queue.push; | ||
var origUnshift = queue.unshift; | ||
queue.push = function(task) { | ||
return new Promise(function(resolve, reject) { | ||
origPush.call(queue, task, function(err) { | ||
if(err) { | ||
reject(err); | ||
} else { | ||
resolve(); | ||
} | ||
}); | ||
}); | ||
}; | ||
queue.unshift = function(task) { | ||
return new Promise(function(resolve, reject) { | ||
origUnshift.call(queue, task, function(err) { | ||
if(err) { | ||
reject(err); | ||
} else { | ||
resolve(); | ||
} | ||
}); | ||
}); | ||
}; | ||
return queue; | ||
}; | ||
exports.priorityQueue = function(promiseWorker, concurrency) { | ||
var callbackWorker = constructIterator(promiseWorker, 1, false, false); | ||
var priorityQueue = async.priorityQueue(callbackWorker, concurrency); | ||
var origPush = priorityQueue.push; | ||
priorityQueue.push = function(task, priority) { | ||
return new Promise(function(resolve, reject) { | ||
origPush.call(priorityQueue, task, priority, function(err) { | ||
if(err) { | ||
reject(err); | ||
} else { | ||
resolve(); | ||
} | ||
}); | ||
}); | ||
}; | ||
return priorityQueue; | ||
}; | ||
exports.cargo = function(promiseWorker, payload) { | ||
var callbackWorker = constructIterator(promiseWorker, 1, false, false); | ||
var cargo = async.cargo(callbackWorker, payload); | ||
var origPush = cargo.push; | ||
cargo.push = function(task) { | ||
return new Promise(function(resolve, reject) { | ||
origPush.call(cargo, task, function(err) { | ||
if(err) { | ||
reject(err); | ||
} else { | ||
resolve(); | ||
} | ||
}); | ||
}); | ||
}; | ||
return cargo; | ||
}; | ||
exports.auto = function(tasks) { | ||
var keys = Object.keys(tasks); | ||
keys.forEach(function(task) { | ||
var promiseFn; | ||
var callbackFn = function(cb, results) { | ||
var promiseFnResult; | ||
try { | ||
promiseFnResult = promiseFn.call(this, results); | ||
} catch(ex) { | ||
cb(ex); | ||
return; | ||
function detectOps(context, values, iter) { | ||
return values.map(function(value) { | ||
return async function() { | ||
if (context.finished) return; | ||
let detected = await iter(value); | ||
if (detected && !context.finished) { | ||
context.finished = true; | ||
context.ret = value; | ||
} | ||
if(promiseFnResult && typeof promiseFnResult.then === 'function') { | ||
promiseFnResult.then(function(value) { | ||
cb(null, value); | ||
}, function(err) { | ||
cb(err, null); | ||
}).then(undefined, function(err) { | ||
setImmediate(function() { | ||
throw err; | ||
}); | ||
}); | ||
} else { | ||
cb(null, promiseFnResult); | ||
} | ||
}; | ||
if(Array.isArray(tasks[task])) { | ||
promiseFn = tasks[task][tasks[task].length - 1]; | ||
tasks[task][tasks[task].length - 1] = callbackFn; | ||
} else { | ||
promiseFn = tasks[task]; | ||
tasks[task] = callbackFn; | ||
} | ||
}); | ||
} | ||
return new Promise(function(resolve, reject) { | ||
async.auto.call(async, tasks, function(err, result) { | ||
if(err) { | ||
reject(err); | ||
} else { | ||
resolve(result); | ||
} | ||
}); | ||
function concatOps(context, values, iter) { | ||
context.ret = []; | ||
return values.map(function(value) { | ||
return async function() { | ||
let results = await iter(value); | ||
context.ret.push(...results); | ||
}; | ||
}); | ||
}; | ||
} | ||
exports.retry = function(opt, task) { | ||
var optObject = { | ||
times: 5, | ||
internal: 0 | ||
}; | ||
if(typeof opt === 'function') { | ||
task = opt; | ||
} else if(typeof opt === 'object' || typeof opt === 'number') { | ||
optObject = opt; | ||
} | ||
callbackTask = constructIterator(task, 0, true, false); | ||
return new Promise(function(resolve, reject) { | ||
regAsync.retry(optObject, callbackTask, function(err, result) { | ||
if(err) { | ||
reject(err); | ||
} else { | ||
resolve(result); | ||
} | ||
}); | ||
function callOps(context, tasks) { | ||
context.ret = new Array(tasks.length); | ||
return tasks.map(function(task, index) { | ||
return async function() { | ||
let retValue = await task(); | ||
context.ret[index] = retValue; | ||
}; | ||
}); | ||
}; | ||
} | ||
exports.apply = async.apply; | ||
exports.nextTick = function(fn) { | ||
if(fn && typeof fn === 'function') { | ||
return async.nextTick(fn); | ||
} else { | ||
return new Promise(function(resolve) { | ||
async.nextTick(resolve); | ||
function timesOps(context, n, iter) { | ||
context.ret = new Array(n); | ||
let tasks = []; | ||
for (let i = 0; i < n; i++) { | ||
tasks.push(async function() { | ||
let retValue = await iter(i); | ||
context.ret[i] = retValue; | ||
}); | ||
} | ||
}; | ||
return tasks; | ||
} | ||
exports.times = function(times, task) { | ||
var callbackTask = constructIterator(task, 1, true, false); | ||
return new Promise(function(resolve, reject) { | ||
async.times(times, callbackTask, function(err, result) { | ||
if(err) { | ||
reject(err); | ||
} else { | ||
resolve(result); | ||
} | ||
}); | ||
function applyOps(context, tasks, ...taskArgs) { | ||
context.ret = new Array(tasks.length); | ||
return tasks.map(function(task, index) { | ||
return async function() { | ||
let retValue = await task(...taskArgs); | ||
context.ret[index] = retValue; | ||
}; | ||
}); | ||
}; | ||
} | ||
exports.timesSeries = function(times, task) { | ||
var callbackTask = constructIterator(task, 1, true, false); | ||
return new Promise(function(resolve, reject) { | ||
async.timesSeries(times, callbackTask, function(err, result) { | ||
if(err) { | ||
reject(err); | ||
} else { | ||
resolve(result); | ||
} | ||
}); | ||
}); | ||
}; | ||
exports.memoize = function(promiseFn, hasher) { | ||
var callbackFn = constructIterator(promiseFn, -1, true, false); | ||
var memoizedFn = async.memoize(callbackFn, hasher); | ||
var returnFn = function() { | ||
var args = Array.prototype.slice.call(arguments, 0); | ||
return new Promise(function(resolve, reject) { | ||
var memoCallbackFn = function(err, result) { | ||
if(err) { | ||
reject(err); | ||
} else { | ||
resolve(result); | ||
} | ||
}; | ||
args.push(memoCallbackFn); | ||
memoizedFn.apply(this, args); | ||
}); | ||
function reduceFunc(reverse = false) { | ||
return async function(values, memo, iter) { | ||
for (let i = 0; i < values.length; i++) { | ||
let curValue = !!reverse ? values[values.length - 1 - i] : values[i]; | ||
memo = await iter(memo, curValue); | ||
} | ||
return memo; | ||
}; | ||
} | ||
returnFn.unmemoize = promiseFn; | ||
returnFn.memo = memoizedFn.memo; | ||
return returnFn; | ||
}; | ||
exports.unmemoize = function(fn) { | ||
return fn.unmemoize; | ||
}; | ||
exports.log = function() { | ||
var args = Array.prototype.slice.call(arguments, 0); | ||
var promiseFn = args.shift(); | ||
var callbackFn = constructIterator(promiseFn, -1, true, false); | ||
args.unshift(callbackFn); | ||
async.log.apply(callbackFn, args); | ||
}; | ||
exports.dir = function() { | ||
var args = Array.prototype.slice.call(arguments, 0); | ||
var promiseFn = args.shift(); | ||
var callbackFn = constructIterator(promiseFn, -1, true, false); | ||
args.unshift(callbackFn); | ||
async.dir.apply(callbackFn, args); | ||
}; | ||
exports.constant = function() { | ||
var self = this; | ||
var args = Array.prototype.slice.call(arguments, 0); | ||
return new Promise(function(resolve) { | ||
var result = regAsync.constant.apply(self, args); | ||
resolve(result); | ||
async function sortBy(values, iter) { | ||
let valueComparators = await (wrapParallel(mapOps))(values, iter); | ||
let objValues = values.map((value, index) => { | ||
return { value, index }; | ||
}); | ||
}; | ||
objValues.sort((a, b) => { | ||
return valueComparators[a.index] - valueComparators[b.index]; | ||
}); | ||
return objValues.map((obj) => obj.value); | ||
} | ||
exports.asyncify = function(func) { | ||
return function() { | ||
var args = Array.prototype.slice.call(arguments, 0); | ||
var result; | ||
try { | ||
result = func.apply(this, args); | ||
} catch (ex) { | ||
return Promise.reject(ex); | ||
function someFunc(invertTruthTest = false) { | ||
return async function(values, iter) { | ||
for (let value of values) { | ||
let pass = await iter(value); | ||
if (invertTruthTest) pass = !pass | ||
if (pass) { | ||
return !invertTruthTest; | ||
} | ||
} | ||
if (result && typeof result.then === 'function') { | ||
return result; | ||
} else { | ||
return Promise.resolve(result); | ||
return invertTruthTest; | ||
} | ||
} | ||
function whilstFunc(doFirst = false, invertTruthTest = false) { | ||
return async function(test, task) { | ||
if (doFirst) { | ||
let tmp = test; | ||
test = task; | ||
task = tmp; | ||
} | ||
}; | ||
}; | ||
let itCount = 0; | ||
let taskRet; | ||
while (true) { | ||
if (!(doFirst && itCount === 0)) { | ||
let testResult = await test(); | ||
if (invertTruthTest) testResult = !testResult; | ||
if (!testResult) break; | ||
} | ||
taskRet = await task(); | ||
itCount++; | ||
} | ||
return taskRet; | ||
} | ||
} | ||
exports.wrapSync = function(fn) { | ||
return exports.asyncify(fn); | ||
}; | ||
async function forever(task) { | ||
while (true) { | ||
await task(); | ||
} | ||
} | ||
exports.during = function() { | ||
var self = this; | ||
var args = Array.prototype.slice.call(arguments, 0); | ||
args[0] = constructIterator(args[0], 0, true, false); | ||
args[1] = constructIterator(args[1], 0, false, false); | ||
return new Promise(function(resolve, reject) { | ||
regAsync.during.call(self, args[0], args[1], function(err) { | ||
if(err) { | ||
reject(err); | ||
async function waterfall(tasks) { | ||
let lastRet; | ||
for (let task of tasks) { | ||
lastRet = await task(lastRet); | ||
} | ||
return lastRet; | ||
} | ||
function compose(...tasks) { | ||
return async function(...initArgs) { | ||
let lastRet; | ||
let taskCounter = 0; | ||
for (let task of tasks) { | ||
if (taskCounter === 0) { | ||
lastRet = await task(...initArgs); | ||
} else { | ||
resolve(); | ||
lastRet = await task(lastRet); | ||
} | ||
}); | ||
}); | ||
}; | ||
taskCounter++; | ||
} | ||
return lastRet; | ||
} | ||
} | ||
exports.doDuring = function() { | ||
var self = this; | ||
var args = Array.prototype.slice.call(arguments, 0); | ||
args[0] = constructIterator(args[0], 0, false, false); | ||
args[1] = constructIterator(args[1], 0, true, false); | ||
return new Promise(function(resolve, reject) { | ||
regAsync.doDuring.call(self, args[0], args[1], function(err) { | ||
if(err) { | ||
reject(err); | ||
} else { | ||
resolve(); | ||
} | ||
function nextTick() { | ||
return new Promise(function(resolve) { | ||
tickFn(function() { | ||
resolve(); | ||
}); | ||
}); | ||
}; | ||
} | ||
exports.nextTick = nextTick; | ||
exports.setImmediate = nextTick; | ||
// exports.doDuring = convertIteratorFunction(regAsync.doDuring, 1, 0, 2, false, false); | ||
// Neo-Async Functions | ||
// fn, iteratorPos, iteratorCallbackPos, callbackPos, iteratorProvidesValue, noErrors | ||
exports.concatLimit = convertIteratorFunction(async.concatLimit, 2, 1, 3, true, false); | ||
exports.mapValues = convertIteratorFunction(async.mapValues, 1, 1, 2, true, false); | ||
exports.mapValuesSeries = convertIteratorFunction(async.mapValuesSeries, 1, 1, 2, true, false); | ||
exports.mapValuesLimit = convertIteratorFunction(async.mapValuesLimit, 2, 1, 3, true, false); | ||
exports.detectLimit = convertIteratorFunction(async.detectLimit, 2, 1, 3, true, true); | ||
exports.everySeries = convertIteratorFunction(async.everySeries, 1, 1, 2, true, true); | ||
exports.everyLimit = convertIteratorFunction(async.everyLimit, 2, 1, 3, false, true); | ||
exports.filterLimit = convertIteratorFunction(async.filterLimit, 2, 1, 3, true, true); | ||
exports.pick = convertIteratorFunction(async.pick, 1, 1, 2, true, true); | ||
exports.pickSeries = convertIteratorFunction(async.pickSeries, 1, 1, 2, true, true); | ||
exports.pickLimit = convertIteratorFunction(async.pickLimit, 2, 1, 3, true, true); | ||
exports.rejectLimit = convertIteratorFunction(async.rejectLimit, 2, 1, 3, true, true); | ||
exports.selectLimit = exports.filterLimit; | ||
exports.someSeries = convertIteratorFunction(async.someSeries, 1, 1, 2, true, true); | ||
exports.someLimit = convertIteratorFunction(async.someLimit, 2, 1, 3, true, true); | ||
exports.sortBySeries = convertIteratorFunction(async.sortBySeries, 1, 1, 2, true, false); | ||
exports.sortByLimit = convertIteratorFunction(async.sortByLimit, 2, 1, 3, true, false); | ||
exports.transform = convertIteratorFunction(async.transform, 1, -1, 2, false, false); | ||
exports.transformSeries = convertIteratorFunction(async.transformSeries, 1, -1, 2, false, false); | ||
exports.transformLimit = convertIteratorFunction(async.transformLimit, 2, -1, 3, false, false); | ||
exports.timesLimit = convertIteratorFunction(async.timesLimit, 2, 1, 3, true, false); | ||
// New Helper Functions | ||
exports.abort = function(err) { | ||
exports.nextTick(function() { | ||
function abort(err) { | ||
tickFn(function() { | ||
throw err; | ||
}); | ||
}; | ||
} | ||
exports.abort = abort; | ||
exports.setTimeout = function(ms) { | ||
function pasyncSetTimeout(ms) { | ||
return new Promise(function(resolve) { | ||
@@ -632,21 +324,22 @@ setTimeout(function() { | ||
}); | ||
}; | ||
} | ||
exports.setTimeout = pasyncSetTimeout; | ||
exports.setImmediate = function() { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(); | ||
}); | ||
}); | ||
}; | ||
function asyncify(fn) { | ||
return async function(...args) { | ||
return await fn(...args); | ||
} | ||
} | ||
exports.asyncify = asyncify; | ||
exports.wrapSync = asyncify; | ||
exports.all = function(initPromises) { | ||
var promiseCtr = 0; | ||
var retPromise; | ||
var retPromiseResolve, retPromiseReject; | ||
var promisesResolved = 0; | ||
var allResolved = false; | ||
var anyRejected = false; | ||
var results = []; | ||
var i; | ||
function pasyncAll(initPromises) { | ||
let promiseCtr = 0; | ||
let retPromise; | ||
let retPromiseResolve, retPromiseReject; | ||
let promisesResolved = 0; | ||
let allResolved = false; | ||
let anyRejected = false; | ||
let results = []; | ||
function setupRetPromise() { | ||
@@ -664,3 +357,3 @@ if (retPromise._pasync) return; | ||
} | ||
var promiseId = promiseCtr++; | ||
let promiseId = promiseCtr++; | ||
if (allResolved) { | ||
@@ -692,2 +385,3 @@ throw new Error('Tried to add promise to pasync.all() after already resolved'); | ||
} | ||
retPromise = new Promise(function(resolve, reject) { | ||
@@ -699,3 +393,3 @@ retPromiseResolve = resolve; | ||
if (initPromises) { | ||
for (i = 0; i < initPromises.length; i++) { | ||
for (let i = 0; i < initPromises.length; i++) { | ||
retPromise.push(initPromises[i]); | ||
@@ -705,5 +399,6 @@ } | ||
return retPromise; | ||
}; | ||
} | ||
exports.all = pasyncAll; | ||
exports.waiter = function() { | ||
let waiter = function() { | ||
var promiseResolve, promiseReject; | ||
@@ -745,1 +440,180 @@ var promiseIsFinished = false; | ||
}; | ||
exports.waiter = waiter; | ||
exports.apply = function(fn, ...args) { | ||
return async function() { | ||
return await fn(...args); | ||
} | ||
} | ||
exports.each = wrapParallel(eachOps); | ||
exports.eachSeries = wrapSeries(eachOps); | ||
exports.eachLimit = wrapLimit(eachOps, { opIndexes: [ 0, 2 ], limitIndex: 1 }); | ||
exports.map = wrapParallel(mapOps); | ||
exports.mapSeries = wrapSeries(mapOps); | ||
exports.mapLimit = wrapLimit(mapOps, { opIndexes: [ 0, 2 ], limitIndex: 1 }); | ||
exports.mapValues = wrapParallel(mapValuesOps); | ||
exports.mapValuesSeries = wrapSeries(mapValuesOps); | ||
exports.mapValuesLimit = wrapLimit(mapValuesOps, { opIndexes: [ 0, 2 ], limitIndex: 1 }); | ||
exports.filter = wrapParallel(filterOps); | ||
exports.filterSeries = wrapSeries(filterOps); | ||
exports.reject = wrapParallel(rejectOps); | ||
exports.rejectSeries = wrapSeries(rejectOps); | ||
exports.detect = wrapParallel(detectOps); | ||
exports.detectSeries = wrapSeries(detectOps); | ||
exports.concat = wrapParallel(concatOps); | ||
exports.concatSeries = wrapSeries(concatOps); | ||
exports.parallel = wrapParallel(callOps); | ||
exports.series = wrapSeries(callOps); | ||
exports.parallelLimit = wrapLimit(callOps, { opIndexes: [ 0 ], limitIndex: 1 }); | ||
exports.times = wrapParallel(timesOps); | ||
exports.timesSeries = wrapSeries(timesOps); | ||
exports.timesLimit = wrapLimit(timesOps); | ||
exports.applyEach = wrapParallel(applyOps); | ||
exports.applyEachSeries = wrapSeries(applyOps); | ||
exports.reduce = reduceFunc(); | ||
exports.reduceRight = reduceFunc(true); | ||
exports.sortBy = sortBy; | ||
exports.some = someFunc(); | ||
exports.every = someFunc(true); | ||
exports.whilst = whilstFunc(false, false), | ||
exports.doWhilst = whilstFunc(true, false); | ||
exports.during = whilstFunc(false, false); | ||
exports.doDuring = whilstFunc(true, false); | ||
exports.until = whilstFunc(false, true); | ||
exports.doUntil = whilstFunc(true, true); | ||
exports.forever = forever; | ||
exports.waterfall = waterfall; | ||
exports.compose = compose; | ||
exports.retry = async function(config, task) { | ||
let times = 5, interval = 0; | ||
if (typeof config === 'number') { | ||
times = config; | ||
} else if (typeof config === 'object') { | ||
if (config.times) times = config.times; | ||
if (config.interval) interval = config.interval; | ||
} else if (typeof config === 'function') { | ||
task = config; | ||
} | ||
let lastError; | ||
for (let i = 0; i < times; i++) { | ||
try { | ||
return await task(); | ||
} catch (err) { | ||
lastError = err; | ||
} | ||
if ((i < times - 1) && (interval > 0)) { | ||
await pasyncSetTimeout(interval); | ||
} | ||
} | ||
throw lastError; | ||
}; | ||
class PasyncQueue { | ||
constructor(taskFn, concurrency) { | ||
this.taskFn = taskFn; | ||
this.concurrency = concurrency; | ||
this.currentRunning = 0; | ||
this.taskQueue = []; | ||
this.hooks = { | ||
taskError: [], | ||
saturated: [], | ||
unsaturated: [], | ||
drain: [] | ||
} | ||
} | ||
async _triggerHook(hookName, hookArgs = []) { | ||
if (!this.hooks[hookName] || this.hooks[hookName].length === 0) { | ||
return; | ||
} | ||
await exports.eachSeries(this.hooks[hookName], async (hookFn) => { | ||
await hookFn(...hookArgs); | ||
}); | ||
} | ||
_checkRunNext() { | ||
if (this.currentRunning >= this.concurrency) return; | ||
if (this.taskQueue.length === 0) return; | ||
let currentTask = this.taskQueue.shift(); | ||
let doTask = async () => { | ||
this.currentRunning += 1; | ||
if (this.currentRunning === this.concurrency) { | ||
await this._triggerHook('saturated', []); | ||
} | ||
try { | ||
await this.taskFn(currentTask); | ||
} catch (err) { | ||
await this._triggerHook('taskError', [ err, currentTask ]); | ||
} | ||
if (this.currentRunning === this.concurrency) { | ||
await this._triggerHook('unsaturated', []); | ||
} | ||
this.currentRunning -= 1; | ||
if (this.currentRunning === 0) { | ||
await this._triggerHook('drain', []); | ||
} | ||
} | ||
doTask() | ||
.then(() => { | ||
tickFn(() => { | ||
this._checkRunNext(); | ||
}); | ||
}) | ||
.catch((err) => abort(err)); | ||
} | ||
error(fn) { | ||
this.hooks.taskError.push(fn); | ||
} | ||
saturated(fn) { | ||
this.hooks.saturated.push(fn); | ||
} | ||
unsaturated(fn) { | ||
this.hooks.unsaturated.push(fn); | ||
} | ||
drain(fn) { | ||
this.hooks.drain.push(fn); | ||
} | ||
length() { | ||
return this.taskQueue.length; | ||
} | ||
running() { | ||
return this.currentRunning; | ||
} | ||
idle() { | ||
return ((this.currentRunning === 0) && (this.taskQueue.length === 0)); | ||
} | ||
push(task) { | ||
if (Array.isArray(task)) { | ||
this.taskQueue.push(...task); | ||
} else { | ||
this.taskQueue.push(task); | ||
} | ||
this._checkRunNext(); | ||
} | ||
unshift(task) { | ||
if (Array.isArray(task)) { | ||
this.taskQueue.unshift(...task); | ||
} else { | ||
this.taskQueue.unshift(task); | ||
} | ||
this._checkRunNext(); | ||
} | ||
} | ||
exports.queue = function(taskFn, concurrency) { | ||
return new PasyncQueue(taskFn, concurrency); | ||
}; | ||
{ | ||
"name": "pasync", | ||
"version": "1.5.0", | ||
"version": "2.0.0", | ||
"license": "MIT", | ||
"description": "Promise-oriented async", | ||
"main": "./lib/index.js", | ||
"license": "MIT", | ||
"repository": { | ||
@@ -19,5 +18,3 @@ "type": "git", | ||
"dependencies": { | ||
"async": "^1.3.0", | ||
"es6-promise": "^2.0.1", | ||
"neo-async": "^0.6.2" | ||
"p-limit": "^3.0.2" | ||
}, | ||
@@ -27,5 +24,8 @@ "devDependencies": { | ||
"jshint": "^2.6.0", | ||
"mocha": "^2.1.0", | ||
"spectrophotometer": "^1.0.1" | ||
"mocha": "8.1.1", | ||
"spectrophotometer": "^3.0.1" | ||
}, | ||
"engines": { | ||
"node": ">= 14.0.0" | ||
} | ||
} |
@@ -37,2 +37,5 @@ # pasync | ||
* mapLimit | ||
* mapValues | ||
* mapValuesSeries | ||
* mapValuesLimit | ||
* filter | ||
@@ -45,6 +48,3 @@ * select | ||
* reduce | ||
* inject | ||
* foldl | ||
* reduceRight | ||
* foldr | ||
* detect | ||
@@ -66,10 +66,6 @@ * detectSeries | ||
* waterfall | ||
* queue | ||
* compose | ||
* seq | ||
* applyEach | ||
* applyEachSeries | ||
* queue | ||
* priorityQueue | ||
* cargo | ||
* auto | ||
* retry | ||
@@ -80,41 +76,7 @@ * apply | ||
* timesSeries | ||
* memoize | ||
* unmemoize | ||
* log | ||
* dir | ||
* constant | ||
* asyncify | ||
* wrapsync | ||
* wrapSync | ||
* during | ||
* doDuring | ||
## Neo-Async Functions Implemented | ||
* concatLimit | ||
* mapValues | ||
* mapValuesSeries | ||
* mapValuesLimit | ||
* detectLimit | ||
* everySeries | ||
* everyLimit | ||
* filterLimit | ||
* pick | ||
* pickSeries | ||
* pickLimit | ||
* rejectLimit | ||
* selectLimit | ||
* someSeries | ||
* someLimit | ||
* sortBySeries | ||
* sortByLimit | ||
* transform | ||
* transformSeries | ||
* transformLimit | ||
* timesLimit | ||
## Functions not implemented | ||
* iterator | ||
* noConflict | ||
## Other Utilities | ||
@@ -121,0 +83,0 @@ |
1213
test/tests.js
@@ -5,3 +5,2 @@ /*jshint -W030 */ | ||
var pasync = require('../lib/index'); | ||
var Promise = require('es6-promise').Promise; | ||
@@ -183,2 +182,60 @@ function setTimeoutPromise(t) { | ||
it('mapValues as object', function(done) { | ||
var arr = { | ||
hello: 1, | ||
goodbye: 2, | ||
dough: 3 | ||
}; | ||
pasync.mapValues(arr, function(el) { | ||
return el + 1; | ||
}).then(function(res) { | ||
expect(res).to.deep.equal({ | ||
hello: 2, | ||
goodbye: 3, | ||
dough: 4 | ||
}); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('mapValuesSeries as object', function(done) { | ||
var arr = { | ||
hello: 1, | ||
goodbye: 2, | ||
dough: 3 | ||
}; | ||
pasync.mapValuesSeries(arr, function(el) { | ||
return el + 1; | ||
}).then(function(res) { | ||
expect(res).to.deep.equal({ | ||
hello: 2, | ||
goodbye: 3, | ||
dough: 4 | ||
}); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('mapValuesLimit', function(done) { | ||
var arr = { | ||
hello: 1, | ||
goodbye: 2, | ||
dough: 3 | ||
}; | ||
pasync.mapValuesLimit(arr, 2, function(el) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(el + 1); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal({ | ||
hello: 2, | ||
goodbye: 3, | ||
dough: 4 | ||
}); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('filter', function(done) { | ||
@@ -652,3 +709,2 @@ var arr = [1, 2, 3]; | ||
function mul3(n) { | ||
expect(this).to.equal(thisTest); | ||
return Promise.resolve(n * 3); | ||
@@ -685,21 +741,2 @@ } | ||
it('seq', function(done) { | ||
var thisTest = {}; | ||
function mul2(n) { | ||
return Promise.resolve(n * 2); | ||
} | ||
function mul3(n) { | ||
expect(this).to.equal(thisTest); | ||
return Promise.resolve(n * 3); | ||
} | ||
function mul4(n) { | ||
return Promise.resolve(n * 4); | ||
} | ||
var composition = pasync.seq(mul2, mul3, mul4); | ||
composition.call(thisTest, 2).then(function(result) { | ||
expect(result).to.equal(48); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('applyEach', function(done) { | ||
@@ -792,14 +829,17 @@ var resultArray = []; | ||
return new Promise(function(resolve, reject) { | ||
responseQueue.push(task * 2); | ||
resolve(); | ||
pasync.setTimeout(50).then(function() { | ||
responseQueue.push(task * 2); | ||
resolve(); | ||
}); | ||
}); | ||
}, 2); | ||
queue.unshift(1).catch(done); | ||
queue.push([2, 3, 4, 5]).catch(done); | ||
queue.unshift(1); | ||
queue.push([2, 3, 4, 5]); | ||
queue.drain = function() { | ||
queue.error(done); | ||
queue.drain(function() { | ||
expect(responseQueue).to.deep.equal([2, 4, 6, 8, 10]); | ||
done(); | ||
}; | ||
}); | ||
}); | ||
@@ -811,189 +851,30 @@ | ||
return new Promise(function(resolve, reject) { | ||
if(task === 4) { | ||
reject(123); | ||
} else { | ||
responseQueue.push(task * 2); | ||
resolve(); | ||
} | ||
}); | ||
}, 2); | ||
queue.unshift(1).catch(done); | ||
queue.push([2, 3]).catch(done); | ||
queue.push(4).then(function() { | ||
throw new Error('should not reach'); | ||
}, function(err) { | ||
expect(err).to.equal(123); | ||
}).catch(done); | ||
queue.push(5).catch(done); | ||
queue.drain = function() { | ||
expect(responseQueue).to.deep.equal([2, 4, 6, 10]); | ||
done(); | ||
}; | ||
}); | ||
it('priorityQueue', function(done) { | ||
var responseQueue = []; | ||
var priorityQueue = pasync.priorityQueue(function(task) { | ||
return new Promise(function(resolve, reject) { | ||
responseQueue.push(task * 2); | ||
resolve(); | ||
}); | ||
}, 2); | ||
priorityQueue.push(1, 3).catch(done); | ||
priorityQueue.push([2, 3, 4, 5], 1).catch(done); | ||
priorityQueue.drain = function() { | ||
expect(responseQueue).to.deep.equal([4, 6, 8, 10, 2]); | ||
done(); | ||
}; | ||
}); | ||
it('priorityQueue with error', function(done) { | ||
var responseQueue = []; | ||
var priorityQueue = pasync.priorityQueue(function(task) { | ||
return new Promise(function(resolve, reject) { | ||
if(task === 4) { | ||
reject(123); | ||
} else { | ||
responseQueue.push(task * 2); | ||
resolve(); | ||
} | ||
}); | ||
}, 2); | ||
priorityQueue.push([2, 3]).catch(done); | ||
priorityQueue.push(4).then(function() { | ||
throw new Error('should not reach'); | ||
}, function(err) { | ||
expect(err).to.equal(123); | ||
}).catch(done); | ||
priorityQueue.push(5).catch(done); | ||
priorityQueue.drain = function() { | ||
expect(responseQueue).to.deep.equal([4, 6, 10]); | ||
done(); | ||
}; | ||
}); | ||
it('cargo', function(done) { | ||
var responseArray = []; | ||
var cargo = pasync.cargo(function(tasks) { | ||
tasks.forEach(function(task) { | ||
responseArray.push(task * 12); | ||
}); | ||
return Promise.resolve(); | ||
}, 5); | ||
cargo.push([1, 2, 3, 4, 5]).catch(done); | ||
cargo.drain = function() { | ||
expect(responseArray).to.deep.equal([12, 24, 36, 48, 60]); | ||
done(); | ||
}; | ||
}); | ||
it('cargo with error', function(done) { | ||
var responseArray = []; | ||
var cargo = pasync.cargo(function(tasks) { | ||
return new Promise(function(resolve, reject) { | ||
var isError = false; | ||
tasks.forEach(function(task) { | ||
if(task === 3) { | ||
isError = true; | ||
pasync.setTimeout(50).then(function() { | ||
if(task === 4) { | ||
reject(123); | ||
} else { | ||
responseArray.push(task * 12); | ||
responseQueue.push(task * 2); | ||
resolve(); | ||
} | ||
}); | ||
if(isError) { | ||
reject(123); | ||
} else { | ||
resolve(); | ||
} | ||
}); | ||
}, 2); | ||
cargo.push([1, 2, 4, 5]).catch(done); | ||
cargo.push(3).then(function() { | ||
throw new Error('should not reach'); | ||
}, function(err) { | ||
expect(err).to.equal(123); | ||
done(); | ||
}).catch(done); | ||
}); | ||
queue.unshift(1); | ||
queue.push([2, 3]); | ||
queue.push(4); | ||
queue.push(5); | ||
it('auto', function(done) { | ||
var responseArray = []; | ||
var auto = pasync.auto({ | ||
get_data: function() { | ||
responseArray.push(2); | ||
return Promise.resolve(2); | ||
}, | ||
da_data: ['get_data', function(results) { | ||
var tempResult = results.get_data * 2; | ||
responseArray.push(tempResult); | ||
return Promise.resolve(tempResult); | ||
}], | ||
get_more_data: ['get_data', 'da_data', function(results) { | ||
var tempResult = results.da_data * 2; | ||
responseArray.push(tempResult); | ||
return Promise.resolve(tempResult); | ||
}] | ||
}).then(function(resultObject) { | ||
expect(responseArray).to.deep.equal([2, 4, 8]); | ||
var gotError = false; | ||
queue.error(function(err) { | ||
if (err !== 123) return done(err); | ||
gotError = true; | ||
}); | ||
queue.drain(function() { | ||
expect(responseQueue).to.deep.equal([2, 4, 6, 10]); | ||
expect(gotError).to.equal(true); | ||
done(); | ||
}).catch(done); | ||
}); | ||
}); | ||
it('auto with value', function(done) { | ||
var responseArray = []; | ||
var auto = pasync.auto({ | ||
get_data: function() { | ||
responseArray.push(2); | ||
return 2; | ||
}, | ||
da_data: ['get_data', function(results) { | ||
var tempResult = results.get_data * 2; | ||
responseArray.push(tempResult); | ||
return Promise.resolve(tempResult); | ||
}], | ||
get_more_data: ['get_data', 'da_data', function(results) { | ||
var tempResult = results.da_data * 2; | ||
responseArray.push(tempResult); | ||
return Promise.resolve(tempResult); | ||
}] | ||
}).then(function(resultObject) { | ||
expect(responseArray).to.deep.equal([2, 4, 8]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('auto with error', function(done) { | ||
var auto = pasync.auto({ | ||
fail_me: function() { | ||
return Promise.reject(123); | ||
} | ||
}).then(function() { | ||
throw new Error('should not reach'); | ||
}, function(err) { | ||
expect(err).to.equal(123); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('auto with throwing error', function(done) { | ||
var auto = pasync.auto({ | ||
fail_me: function() { | ||
throw(123); | ||
} | ||
}).then(function() { | ||
throw new Error('should not reach'); | ||
}, function(err) { | ||
expect(err).to.equal(123); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('retry', function(done) { | ||
@@ -1128,4 +1009,7 @@ var responseArray = []; | ||
new Promise(function(resolve) { | ||
pasync.nextTick(resolve); | ||
resultArray.push(1); | ||
pasync.nextTick() | ||
.then(function() { | ||
resultArray.push(1); | ||
resolve(); | ||
}); | ||
}).then(function() { | ||
@@ -1222,145 +1106,2 @@ resultArray.push(2); | ||
it('memoize', function(done) { | ||
var responseArray = []; | ||
var memoCount = 0; | ||
var myFunc = function(up, down, no) { | ||
memoCount++; | ||
return Promise.resolve(up * down * no); | ||
}; | ||
var myMemo = pasync.memoize(myFunc); | ||
myMemo(2, 4, 3).then(function(result) { | ||
responseArray.push(result); | ||
expect(result).to.equal(24); | ||
}).then(function() { | ||
myMemo(0, 4, 3).then(function(result) { | ||
responseArray.push(result); | ||
expect(result).to.equal(0); | ||
}).then(function() { | ||
myMemo(2, 4, 3).then(function(result) { | ||
responseArray.push(result); | ||
expect(result).to.equal(24); | ||
}).then(function() { | ||
expect(responseArray).to.contain(24); | ||
expect(responseArray).to.contain(0); | ||
expect(Object.keys(myMemo.memo).length).to.equal(2); | ||
expect(memoCount).to.equal(2); | ||
done(); | ||
}).catch(done); | ||
}); | ||
}); | ||
}); | ||
it('memoize with hasher', function(done) { | ||
var responseArray = []; | ||
var memoCount = 0; | ||
var hasher = function() { | ||
var hashed = 1; | ||
var args = Array.prototype.slice.call(arguments, 0); | ||
args.forEach(function(arg) { | ||
hashed *= arg; | ||
}); | ||
return hashed; | ||
}; | ||
var myFunc = function(up, down, no) { | ||
memoCount++; | ||
return Promise.resolve(up * down * no); | ||
}; | ||
var myMemo = pasync.memoize(myFunc, hasher); | ||
myMemo(2, 4, 3).then(function(result) { | ||
responseArray.push(result); | ||
expect(result).to.equal(24); | ||
}).then(function() { | ||
myMemo(0, 4, 3).then(function(result) { | ||
responseArray.push(result); | ||
expect(result).to.equal(0); | ||
}).then(function() { | ||
myMemo(2, 4, 3).then(function(result) { | ||
responseArray.push(result); | ||
expect(result).to.equal(24); | ||
}).then(function() { | ||
expect(responseArray).to.deep.equal([24, 0, 24]); | ||
expect(responseArray).to.contain(0); | ||
expect(Object.keys(myMemo.memo).length).to.equal(2); | ||
expect(memoCount).to.equal(2); | ||
done(); | ||
}).catch(done); | ||
}); | ||
}); | ||
}); | ||
it('unmemoize', function(done) { | ||
var memoCount = 0; | ||
var responseArray = []; | ||
var myMemo; | ||
var myFunc = function(up) { | ||
memoCount++; | ||
return Promise.resolve(up * 2); | ||
}; | ||
myMemo = pasync.memoize(myFunc); | ||
var noMemo = pasync.unmemoize(myMemo); | ||
noMemo(2).then(function(result) { | ||
responseArray.push(result); | ||
}).then(function() { | ||
noMemo(2).then(function(result) { | ||
responseArray.push(result); | ||
}).then(function() { | ||
noMemo(12).then(function(result) { | ||
responseArray.push(result); | ||
}).then(function(){ | ||
expect(typeof myMemo.unmemoize).to.equal('function'); | ||
expect(Object.keys(myMemo.memo).length).to.equal(0); | ||
expect(noMemo.memo).to.equal(undefined); | ||
expect(noMemo.unmemoize).to.equal(undefined); | ||
expect(memoCount).to.equal(3); | ||
expect(responseArray).to.deep.equal([4, 4, 24]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
}); | ||
}); | ||
it('log', function(done) { | ||
var logFn = function(arg1, arg2) { | ||
return Promise.resolve(arg1 * arg2); | ||
// Logs '6' to the console | ||
}; | ||
pasync.log(logFn, 2, 3); | ||
done(); | ||
}); | ||
it('dir', function(done) { | ||
var dirFn = function(arg1, arg2) { | ||
var obj = { | ||
a: arg1, | ||
b: arg2 | ||
}; | ||
return Promise.resolve(obj); | ||
// Logs '{a: 2, b: 3}' to the console | ||
}; | ||
pasync.dir(dirFn, 2, 3); | ||
done(); | ||
}); | ||
it('constant', function(done) { | ||
pasync.constant('Pasync rules!').then(function(result) { | ||
result(function(err, word) { | ||
expect(word).to.equal('Pasync rules!'); | ||
done(); | ||
}); | ||
}).catch(done); | ||
}); | ||
it('constant with multiple arguments', function(done) { | ||
pasync.constant('a', 2, 'c').then(function(result) { | ||
result(function(err, a, b, c) { | ||
expect(a).to.equal('a'); | ||
expect(b).to.equal(2); | ||
expect(c).to.equal('c'); | ||
done(); | ||
}); | ||
}).catch(done); | ||
}); | ||
it('asyncify', function(done) { | ||
@@ -1386,3 +1127,2 @@ var xyz = pasync.asyncify(function(x, y, z) { | ||
}, function(err) { | ||
console.log(err); | ||
expect(err).to.exist; | ||
@@ -1394,3 +1134,3 @@ done(); | ||
it('wrapSync', function(done) { | ||
var xyz = pasync.asyncify(function(x, y, z) { | ||
var xyz = pasync.wrapSync(function(x, y, z) { | ||
expect(x).to.equal(1); | ||
@@ -1406,773 +1146,2 @@ expect(y).to.equal(2); | ||
describe('Neo-Async Improvement of Convenience Support', function() { | ||
var testObject = { | ||
notRed: 'red', | ||
notGreen: 'green', | ||
notBlue: 'blue' | ||
}; | ||
var numTestObject = { | ||
one: 1, | ||
two: 2, | ||
three: 3 | ||
}; | ||
it('each with object', function(done) { | ||
var res = []; | ||
pasync.each(testObject, function(el) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
res.push(el); | ||
resolve(); | ||
}); | ||
}); | ||
}).then(function() { | ||
expect(res).to.contain('red'); | ||
expect(res).to.contain('blue'); | ||
expect(res).to.contain('green'); | ||
expect(res).to.have.length(3); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('each with values', function(done) { | ||
var res = []; | ||
pasync.each(numTestObject, function(el) { | ||
res.push(el); | ||
}).then(function() { | ||
expect(res).to.contain(1); | ||
expect(res).to.contain(2); | ||
expect(res).to.contain(3); | ||
expect(res).to.have.length(3); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('eachSeries', function(done) { | ||
var res = []; | ||
pasync.eachSeries(testObject, function(el) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
res.push(el); | ||
resolve(); | ||
}); | ||
}); | ||
}).then(function() { | ||
expect(res).to.contain('red'); | ||
expect(res).to.contain('blue'); | ||
expect(res).to.contain('green'); | ||
expect(res).to.have.length(3); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('eachLimit', function(done) { | ||
var res = []; | ||
pasync.eachLimit(testObject, 2, function(el) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
res.push(el); | ||
resolve(); | ||
}); | ||
}); | ||
}).then(function() { | ||
expect(res).to.contain('red'); | ||
expect(res).to.contain('blue'); | ||
expect(res).to.contain('green'); | ||
expect(res).to.have.length(3); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('map with promises', function(done) { | ||
pasync.map(numTestObject, function(el) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(el + 1); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal([ 2, 3, 4 ]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('map with values', function(done) { | ||
pasync.map(numTestObject, function(el) { | ||
return el + 1; | ||
}).then(function(res) { | ||
expect(res).to.deep.equal([2, 3, 4]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('mapSeries', function(done) { | ||
pasync.mapSeries(numTestObject, function(el) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(el + 1); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal([2, 3, 4]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('mapLimit', function(done) { | ||
pasync.mapLimit(numTestObject, 2, function(el) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(el + 1); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal([2, 3, 4]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('filter', function(done) { | ||
pasync.filter(numTestObject, function(el) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(el > 1); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal([2, 3]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('filterSeries', function(done) { | ||
pasync.filterSeries(numTestObject, function(el) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(el > 1); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal([2, 3]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('reject', function(done) { | ||
pasync.reject(numTestObject, function(el) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(el > 1); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal([1]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('rejectSeries', function(done) { | ||
pasync.rejectSeries(numTestObject, function(el) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(el > 1); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal([1]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('reduce', function(done) { | ||
pasync.reduce(numTestObject, 0, function(memo, item) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(memo + item); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.equal(6); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('reduceRight', function(done) { | ||
pasync.reduceRight(numTestObject, 0, function(memo, item) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(memo + item); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.equal(6); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('detect', function(done) { | ||
pasync.detect(numTestObject, function(item) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(item === 2); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.equal(2); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('detectSeries', function(done) { | ||
pasync.detectSeries(numTestObject, function(item) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(item === 2); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.equal(2); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('sortBy', function(done) { | ||
var unorderedNumTestObject = { | ||
one: 2, | ||
two: 3, | ||
three: 1 | ||
}; | ||
pasync.sortBy(unorderedNumTestObject, function(item) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(item); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal([1, 2, 3]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('some', function(done) { | ||
pasync.some(numTestObject, function(item) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(item === 2); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.equal(true); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('every', function(done) { | ||
pasync.every(numTestObject, function(item) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(item === 2); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.equal(false); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('concat', function(done) { | ||
var specialNumTestObject = { | ||
one: [1, 2], | ||
four: [3, 4] | ||
}; | ||
pasync.concat(specialNumTestObject, function(item) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(item); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal([1, 2, 3, 4]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('concatSeries', function(done) { | ||
var specialNumTestObject = { | ||
one: [1, 2], | ||
four: [3, 4] | ||
}; | ||
pasync.concatSeries(specialNumTestObject, function(item) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(item); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal([1, 2, 3, 4]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('parallel as Object', function(done) { | ||
var a = false, b = false; | ||
var funcs = { | ||
funcOne: function() { | ||
return new Promise(function(resolve) { | ||
a = true; | ||
resolve(1); | ||
}); | ||
}, | ||
funcTwo: function() { | ||
return new Promise(function(resolve) { | ||
b = true; | ||
resolve(2); | ||
}); | ||
} | ||
}; | ||
pasync.parallel(funcs).then(function(result) { | ||
expect(result.funcOne).to.equal(1); | ||
expect(result.funcTwo).to.equal(2); | ||
expect(a).to.be.true; | ||
expect(b).to.be.true; | ||
done(); | ||
}).catch(done); | ||
}); | ||
}); | ||
describe('Neo-Async features', function() { | ||
it('concatLimit', function(done) { | ||
var arr = [[1, 2], [3, 4]]; | ||
pasync.concatLimit(arr, 17, function(item) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(item); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal([1, 2, 3, 4]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('mapValues as array', function(done) { | ||
var arr = [1, 2, 3]; | ||
pasync.mapValues(arr, function(el) { | ||
return el + 1; | ||
}).then(function(res) { | ||
expect(res).to.deep.equal({ | ||
0: 2, | ||
1: 3, | ||
2: 4 | ||
}); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('mapValues as object', function(done) { | ||
var arr = { | ||
hello: 1, | ||
goodbye: 2, | ||
dough: 3 | ||
}; | ||
pasync.mapValues(arr, function(el) { | ||
return el + 1; | ||
}).then(function(res) { | ||
expect(res).to.deep.equal({ | ||
hello: 2, | ||
goodbye: 3, | ||
dough: 4 | ||
}); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('mapValuesSeries as array', function(done) { | ||
var arr = [1, 2, 3]; | ||
pasync.mapValuesSeries(arr, function(el) { | ||
return el + 1; | ||
}).then(function(res) { | ||
expect(res).to.deep.equal({ | ||
0: 2, | ||
1: 3, | ||
2: 4 | ||
}); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('mapValuesSeries as object', function(done) { | ||
var arr = { | ||
hello: 1, | ||
goodbye: 2, | ||
dough: 3 | ||
}; | ||
pasync.mapValuesSeries(arr, function(el) { | ||
return el + 1; | ||
}).then(function(res) { | ||
expect(res).to.deep.equal({ | ||
hello: 2, | ||
goodbye: 3, | ||
dough: 4 | ||
}); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('mapValuesLimit', function(done) { | ||
var arr = { | ||
hello: 1, | ||
goodbye: 2, | ||
dough: 3 | ||
}; | ||
pasync.mapValuesLimit(arr, 2, function(el) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(el + 1); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal({ | ||
hello: 2, | ||
goodbye: 3, | ||
dough: 4 | ||
}); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('detectLimit', function(done) { | ||
var arr = [1, 2, 3]; | ||
pasync.detectLimit(arr, 1, function(item) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(item === 2); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.equal(2); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('everySeries', function(done) { | ||
var arr = [1, 2, 3]; | ||
pasync.everySeries(arr, function(item) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(item === 2); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.equal(false); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('everyLimit', function(done) { | ||
var arr = [1, 2, 3]; | ||
pasync.everyLimit(arr, 2, function(item) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(item === 2); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.equal(false); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('filterLimit', function(done) { | ||
var arr = [1, 2, 3]; | ||
pasync.filterLimit(arr, 2, function(el) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(el > 1); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal([2, 3]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('pick with array', function(done) { | ||
var arr = [1, 3, 2, 4]; | ||
var responseArray = []; | ||
pasync.pick(arr, function(num) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
responseArray.push(num); | ||
resolve(num % 2); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal([1, 3]); | ||
expect(responseArray).to.deep.equal([1, 3, 2, 4]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('pick with object', function(done) { | ||
var arr = { | ||
a: 4, | ||
b: 3, | ||
c: 2 | ||
}; | ||
var responseArray = []; | ||
pasync.pick(arr, function(num) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
responseArray.push(num); | ||
resolve(num % 2); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal({ | ||
b: 3 | ||
}); | ||
expect(responseArray).to.deep.equal([4, 3, 2]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('pickSeries with array', function(done) { | ||
var arr = [1, 3, 2, 4]; | ||
var responseArray = []; | ||
pasync.pickSeries(arr, function(num) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
responseArray.push(num); | ||
resolve(num % 2); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal([1, 3]); | ||
expect(responseArray).to.deep.equal([1, 3, 2, 4]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('pickSeries with object', function(done) { | ||
var arr = { | ||
a: 4, | ||
b: 3, | ||
c: 2 | ||
}; | ||
var responseArray = []; | ||
pasync.pickSeries(arr, function(num) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
responseArray.push(num); | ||
resolve(num % 2); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal({ | ||
b: 3 | ||
}); | ||
expect(responseArray).to.deep.equal([4, 3, 2]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('pickLimit with array', function(done) { | ||
var responseArray = []; | ||
var arr = [1, 5, 3, 2, 4]; | ||
pasync.pickLimit(arr, 2, function(num) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
responseArray.push(num); | ||
resolve(num % 2); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal([1, 5, 3]); | ||
expect(responseArray).to.deep.equal([1, 5, 3, 2, 4]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('pickLimit with object', function(done) { | ||
var responseArray = []; | ||
var arr = { | ||
a: 1, | ||
b: 5, | ||
c: 3, | ||
d: 2, | ||
e: 4 | ||
}; | ||
pasync.pickLimit(arr, 2, function(num) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
responseArray.push(num); | ||
resolve(num % 2); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal({ | ||
a: 1, | ||
b: 5, | ||
c: 3 | ||
}); | ||
expect(responseArray).to.deep.equal([1, 5, 3, 2, 4]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('rejectLimit', function(done) { | ||
var arr = [1, 2, 3]; | ||
pasync.rejectLimit(arr, 1, function(el) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(el > 1); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal([1]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('someSeries', function(done) { | ||
var arr = [1, 2, 3]; | ||
pasync.someSeries(arr, function(item) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(item === 2); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.equal(true); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('someLimit', function(done) { | ||
var arr = [1, 2, 3]; | ||
pasync.someLimit(arr, 2, function(item) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(item === 2); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.equal(true); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('sortBySeries', function(done) { | ||
var arr = [3, 5, 2, 1, 4]; | ||
pasync.sortBySeries(arr, function(item) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(item); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal([1, 2, 3, 4, 5]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('sortByLimit', function(done) { | ||
var arr = [3, 5, 2, 1, 4]; | ||
pasync.sortByLimit(arr, 3, function(item) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
resolve(item); | ||
}); | ||
}); | ||
}).then(function(res) { | ||
expect(res).to.deep.equal([1, 2, 3, 4, 5]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('transform', function(done) { | ||
var arr = [1, 5, 3, 2, 4]; | ||
var responseArray = []; | ||
pasync.transform(arr, function(memo, num) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
if(num % 2 === 1) { | ||
if(Array.isArray(memo)) { | ||
memo.push(num); | ||
} | ||
} | ||
responseArray.push(num); | ||
resolve(); | ||
}); | ||
}); | ||
}).then(function(res){ | ||
expect(res).to.deep.equal([1, 5, 3]); | ||
expect(responseArray).to.deep.equal([1, 5, 3, 2, 4]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('transformSeries', function(done) { | ||
var arr = [1, 3, 2, 4]; | ||
var responseArray = []; | ||
pasync.transformSeries(arr, function(memo, num) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
if(num % 2 === 1) { | ||
if(Array.isArray(memo)) { | ||
memo.push(num); | ||
} | ||
} | ||
responseArray.push(num); | ||
resolve(); | ||
}); | ||
}); | ||
}).then(function(res){ | ||
expect(res).to.deep.equal([1, 3]); | ||
expect(responseArray).to.deep.equal([1, 3, 2, 4]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('transformLimit', function(done) { | ||
var arr = [1, 5, 3, 2, 4]; | ||
var responseArray = []; | ||
pasync.transformLimit(arr, 2, function(memo, num) { | ||
return new Promise(function(resolve) { | ||
setImmediate(function() { | ||
if(num % 2 === 1) { | ||
if(Array.isArray(memo)) { | ||
memo.push(num); | ||
} | ||
} | ||
responseArray.push(num); | ||
resolve(); | ||
}); | ||
}); | ||
}).then(function(res){ | ||
expect(res).to.deep.equal([1, 5, 3]); | ||
expect(responseArray).to.deep.equal([1, 5, 3, 2, 4]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('timesLimit', function(done) { | ||
var timesCount = 0; | ||
var timesTest = 2; | ||
return pasync.timesLimit(8, 2, function(n, next) { | ||
timesCount++; | ||
timesTest = timesTest * 2; | ||
return Promise.resolve(timesCount); | ||
}).then(function(result) { | ||
expect(timesCount).to.equal(8); | ||
expect(timesTest).to.equal(512); | ||
expect(result).to.deep.equal([ 1, 2, 3, 4, 5, 6, 7, 8 ]); | ||
done(); | ||
}).catch(done); | ||
}); | ||
}); | ||
describe('Utilities', function() { | ||
@@ -2179,0 +1148,0 @@ |
1
52566
7
1862
182
+ Addedp-limit@^3.0.2
+ Addedp-limit@3.1.0(transitive)
+ Addedyocto-queue@0.1.0(transitive)
- Removedasync@^1.3.0
- Removedes6-promise@^2.0.1
- Removedneo-async@^0.6.2
- Removedasync@1.5.2(transitive)
- Removedes6-promise@2.3.0(transitive)
- Removedneo-async@0.6.5(transitive)