UNPKG

fa

Version:

fluent async: functional programming support for asynchronous functions.

254 lines (249 loc) 7.5 kB
(function() { var fa; fa = function(concurrency, do_all, with_index) { var api, nullFn, tmpl; if (concurrency == null) concurrency = Number.MAX_VALUE; if (do_all == null) do_all = false; if (with_index == null) with_index = false; if (typeof process === "undefined" || process === null) process = {}; if (process.nextTick == null) { process.nextTick = function(cb) { return cb(); }; } api = {}; api.reduce = function(arr, memo, iterator, callback) { var count, errs, isArray, keys, nextItem, pending, size, theCallback; isArray = Array.isArray(arr); try { keys = isArray ? arr : Object.keys(arr); } catch (e) { return callback(new Error("Trying to reduce over non iterable")); } if (!keys.length) return callback(void 0, memo); if (do_all) errs = []; size = pending = keys.length; count = 0; theCallback = function(err, result) { if (err) { if (errs) { errs.push(err); } else { callback(err); callback = function() {}; return; } } else { } if (--pending === 0) { err = errs && errs.length ? errs : void 0; return callback(err, result); } return process.nextTick(function() { return nextItem(result); }); }; nextItem = function(memo) { var key, val; if (isArray) { val = arr[count++]; return iterator(memo, val, theCallback); } else { key = keys[count++]; val = arr[key]; return iterator(memo, val, key, theCallback); } }; return nextItem(memo); }; nullFn = function() { return; }; tmpl = function(name, initResults, single_argument_callback, handleResult, handleReturn) { return function(arr, iterator, callback, what) { var count, errs, finished, i, isArray, keys, nextItem, pending, results, size, theCallback, workers, _ref, _results; if (what == null) what = 0; isArray = Array.isArray(arr); keys = isArray ? arr : Object.keys(arr); results = initResults(); if (!keys.length) { if (single_argument_callback) { return callback(results); } else { return callback(void 0, results); } } if (do_all) errs = []; workers = 0; size = pending = keys.length; count = 0; finished = false; theCallback = function(val, index) { return function(err, result) { workers -= 1; if (single_argument_callback) { result = err; err = null; } if (err) { if (errs) { errs.push(err); } else { callback(err); callback = function() {}; return; } } else { results = handleResult(results, result, val, index, callback); if (results === true) { callback = function() {}; finished = true; return; } } if (--pending === 0) { err = errs && errs.length ? errs : void 0; if (handleReturn) { return handleReturn(err, callback, results, size); } else { return callback(err, results); } } return process.nextTick(function() { return nextItem(); }); }; }; nextItem = function() { var index, key, val; if (workers++ < concurrency && count < size && !finished) { index = count++; if (isArray) { val = arr[index]; if (with_index) { return iterator(val, index, theCallback(val, index)); } else { return iterator(val, theCallback(val, index)); } } else { key = keys[index]; val = arr[key]; if (with_index) { return iterator(val, key, index, theCallback(val, index)); } else { return iterator(val, key, theCallback(val, index)); } } } }; _results = []; for (i = 1, _ref = (concurrency < pending ? concurrency : pending); 1 <= _ref ? i <= _ref : i >= _ref; 1 <= _ref ? i++ : i--) { _results.push(nextItem()); } return _results; }; }; api.each = tmpl('each', nullFn, false, nullFn); api.map = tmpl('map', (function() { return []; }), false, function(results, result, val, index) { results[index] = result; return results; }); api.concat = tmpl('concat', (function() { return []; }), false, function(results, result) { if (Array.isArray(result)) { return results.concat(result); } else { return results; } }); api.filter = tmpl('filter', (function() { return []; }), true, function(results, result, val) { if (result) results.push(val); return results; }); api.reject = tmpl('reject', (function() { return []; }), true, function(results, result, val) { if (!result) results.push(val); return results; }); api.detect = tmpl('detect', (function() { return; }), true, function(results, result, val, index, callback) { if (results === void 0) results = 0; if (result) { callback(val, results); return true; } return ++results; }); api.any = tmpl('any', (function() { return false; }), true, (function(results, result, val, index, callback) { if (result) { callback(true); return true; } }), function(err, callback) { return callback(false); }); api.all = tmpl('all', (function() { return true; }), true, (function(results, result, val, index, callback) { if (results === true) results = 0; if (result) { return ++results; } else { return results; } }), function(err, callback, results, size) { return callback(results === size); }); api.queue = function(concurrency) { return fa(concurrency, do_all, with_index); }; api.series = function() { return fa(1, do_all, with_index); }; api.with_index = function() { return fa(concurrency, do_all, true); }; api["continue"] = function() { return fa(concurrency, true, with_index); }; api.forEach = api.each; api.select = api.filter; api.find = api.detect; api.inject = api.reduce; api.foldl = api.reduce; api.some = api.any; api.every = api.all; api.concurrent = api.queue; api.c = api.queue; api["if"] = function(conditional, trueFn, elseFn, callback) { if (!callback) { callback = elseFn; elseFn = null; } if (conditional) { return trueFn(callback); } else { if (elseFn) { return elseFn(callback); } else { return callback(); } } }; return api; }; if (typeof module !== 'undefined') { module.exports = fa(); } else { window.fa = fa(); } }).call(this);