PageRenderTime 64ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 1ms

/front/node_modules/bower/lib/node_modules/handlebars/node_modules/async/lib/async.js

https://gitlab.com/boxnia/NFU_MOVIL
JavaScript | 1265 lines | 1067 code | 149 blank | 49 comment | 199 complexity | 87487eb46edaa0080452668793c557f4 MD5 | raw file
  1. /*!
  2. * async
  3. * https://github.com/caolan/async
  4. *
  5. * Copyright 2010-2014 Caolan McMahon
  6. * Released under the MIT license
  7. */
  8. (function () {
  9. var async = {};
  10. function noop() {}
  11. function identity(v) {
  12. return v;
  13. }
  14. function toBool(v) {
  15. return !!v;
  16. }
  17. function notId(v) {
  18. return !v;
  19. }
  20. // global on the server, window in the browser
  21. var previous_async;
  22. // Establish the root object, `window` (`self`) in the browser, `global`
  23. // on the server, or `this` in some virtual machines. We use `self`
  24. // instead of `window` for `WebWorker` support.
  25. var root = typeof self === 'object' && self.self === self && self ||
  26. typeof global === 'object' && global.global === global && global ||
  27. this;
  28. if (root != null) {
  29. previous_async = root.async;
  30. }
  31. async.noConflict = function () {
  32. root.async = previous_async;
  33. return async;
  34. };
  35. function only_once(fn) {
  36. return function() {
  37. if (fn === null) throw new Error("Callback was already called.");
  38. fn.apply(this, arguments);
  39. fn = null;
  40. };
  41. }
  42. function _once(fn) {
  43. return function() {
  44. if (fn === null) return;
  45. fn.apply(this, arguments);
  46. fn = null;
  47. };
  48. }
  49. //// cross-browser compatiblity functions ////
  50. var _toString = Object.prototype.toString;
  51. var _isArray = Array.isArray || function (obj) {
  52. return _toString.call(obj) === '[object Array]';
  53. };
  54. // Ported from underscore.js isObject
  55. var _isObject = function(obj) {
  56. var type = typeof obj;
  57. return type === 'function' || type === 'object' && !!obj;
  58. };
  59. function _isArrayLike(arr) {
  60. return _isArray(arr) || (
  61. // has a positive integer length property
  62. typeof arr.length === "number" &&
  63. arr.length >= 0 &&
  64. arr.length % 1 === 0
  65. );
  66. }
  67. function _arrayEach(arr, iterator) {
  68. var index = -1,
  69. length = arr.length;
  70. while (++index < length) {
  71. iterator(arr[index], index, arr);
  72. }
  73. }
  74. function _map(arr, iterator) {
  75. var index = -1,
  76. length = arr.length,
  77. result = Array(length);
  78. while (++index < length) {
  79. result[index] = iterator(arr[index], index, arr);
  80. }
  81. return result;
  82. }
  83. function _range(count) {
  84. return _map(Array(count), function (v, i) { return i; });
  85. }
  86. function _reduce(arr, iterator, memo) {
  87. _arrayEach(arr, function (x, i, a) {
  88. memo = iterator(memo, x, i, a);
  89. });
  90. return memo;
  91. }
  92. function _forEachOf(object, iterator) {
  93. _arrayEach(_keys(object), function (key) {
  94. iterator(object[key], key);
  95. });
  96. }
  97. function _indexOf(arr, item) {
  98. for (var i = 0; i < arr.length; i++) {
  99. if (arr[i] === item) return i;
  100. }
  101. return -1;
  102. }
  103. var _keys = Object.keys || function (obj) {
  104. var keys = [];
  105. for (var k in obj) {
  106. if (obj.hasOwnProperty(k)) {
  107. keys.push(k);
  108. }
  109. }
  110. return keys;
  111. };
  112. function _keyIterator(coll) {
  113. var i = -1;
  114. var len;
  115. var keys;
  116. if (_isArrayLike(coll)) {
  117. len = coll.length;
  118. return function next() {
  119. i++;
  120. return i < len ? i : null;
  121. };
  122. } else {
  123. keys = _keys(coll);
  124. len = keys.length;
  125. return function next() {
  126. i++;
  127. return i < len ? keys[i] : null;
  128. };
  129. }
  130. }
  131. // Similar to ES6's rest param (http://ariya.ofilabs.com/2013/03/es6-and-rest-parameter.html)
  132. // This accumulates the arguments passed into an array, after a given index.
  133. // From underscore.js (https://github.com/jashkenas/underscore/pull/2140).
  134. function _restParam(func, startIndex) {
  135. startIndex = startIndex == null ? func.length - 1 : +startIndex;
  136. return function() {
  137. var length = Math.max(arguments.length - startIndex, 0);
  138. var rest = Array(length);
  139. for (var index = 0; index < length; index++) {
  140. rest[index] = arguments[index + startIndex];
  141. }
  142. switch (startIndex) {
  143. case 0: return func.call(this, rest);
  144. case 1: return func.call(this, arguments[0], rest);
  145. }
  146. // Currently unused but handle cases outside of the switch statement:
  147. // var args = Array(startIndex + 1);
  148. // for (index = 0; index < startIndex; index++) {
  149. // args[index] = arguments[index];
  150. // }
  151. // args[startIndex] = rest;
  152. // return func.apply(this, args);
  153. };
  154. }
  155. function _withoutIndex(iterator) {
  156. return function (value, index, callback) {
  157. return iterator(value, callback);
  158. };
  159. }
  160. //// exported async module functions ////
  161. //// nextTick implementation with browser-compatible fallback ////
  162. // capture the global reference to guard against fakeTimer mocks
  163. var _setImmediate = typeof setImmediate === 'function' && setImmediate;
  164. var _delay = _setImmediate ? function(fn) {
  165. // not a direct alias for IE10 compatibility
  166. _setImmediate(fn);
  167. } : function(fn) {
  168. setTimeout(fn, 0);
  169. };
  170. if (typeof process === 'object' && typeof process.nextTick === 'function') {
  171. async.nextTick = process.nextTick;
  172. } else {
  173. async.nextTick = _delay;
  174. }
  175. async.setImmediate = _setImmediate ? _delay : async.nextTick;
  176. async.forEach =
  177. async.each = function (arr, iterator, callback) {
  178. return async.eachOf(arr, _withoutIndex(iterator), callback);
  179. };
  180. async.forEachSeries =
  181. async.eachSeries = function (arr, iterator, callback) {
  182. return async.eachOfSeries(arr, _withoutIndex(iterator), callback);
  183. };
  184. async.forEachLimit =
  185. async.eachLimit = function (arr, limit, iterator, callback) {
  186. return _eachOfLimit(limit)(arr, _withoutIndex(iterator), callback);
  187. };
  188. async.forEachOf =
  189. async.eachOf = function (object, iterator, callback) {
  190. callback = _once(callback || noop);
  191. object = object || [];
  192. var iter = _keyIterator(object);
  193. var key, completed = 0;
  194. while ((key = iter()) != null) {
  195. completed += 1;
  196. iterator(object[key], key, only_once(done));
  197. }
  198. if (completed === 0) callback(null);
  199. function done(err) {
  200. completed--;
  201. if (err) {
  202. callback(err);
  203. }
  204. // Check key is null in case iterator isn't exhausted
  205. // and done resolved synchronously.
  206. else if (key === null && completed <= 0) {
  207. callback(null);
  208. }
  209. }
  210. };
  211. async.forEachOfSeries =
  212. async.eachOfSeries = function (obj, iterator, callback) {
  213. callback = _once(callback || noop);
  214. obj = obj || [];
  215. var nextKey = _keyIterator(obj);
  216. var key = nextKey();
  217. function iterate() {
  218. var sync = true;
  219. if (key === null) {
  220. return callback(null);
  221. }
  222. iterator(obj[key], key, only_once(function (err) {
  223. if (err) {
  224. callback(err);
  225. }
  226. else {
  227. key = nextKey();
  228. if (key === null) {
  229. return callback(null);
  230. } else {
  231. if (sync) {
  232. async.setImmediate(iterate);
  233. } else {
  234. iterate();
  235. }
  236. }
  237. }
  238. }));
  239. sync = false;
  240. }
  241. iterate();
  242. };
  243. async.forEachOfLimit =
  244. async.eachOfLimit = function (obj, limit, iterator, callback) {
  245. _eachOfLimit(limit)(obj, iterator, callback);
  246. };
  247. function _eachOfLimit(limit) {
  248. return function (obj, iterator, callback) {
  249. callback = _once(callback || noop);
  250. obj = obj || [];
  251. var nextKey = _keyIterator(obj);
  252. if (limit <= 0) {
  253. return callback(null);
  254. }
  255. var done = false;
  256. var running = 0;
  257. var errored = false;
  258. (function replenish () {
  259. if (done && running <= 0) {
  260. return callback(null);
  261. }
  262. while (running < limit && !errored) {
  263. var key = nextKey();
  264. if (key === null) {
  265. done = true;
  266. if (running <= 0) {
  267. callback(null);
  268. }
  269. return;
  270. }
  271. running += 1;
  272. iterator(obj[key], key, only_once(function (err) {
  273. running -= 1;
  274. if (err) {
  275. callback(err);
  276. errored = true;
  277. }
  278. else {
  279. replenish();
  280. }
  281. }));
  282. }
  283. })();
  284. };
  285. }
  286. function doParallel(fn) {
  287. return function (obj, iterator, callback) {
  288. return fn(async.eachOf, obj, iterator, callback);
  289. };
  290. }
  291. function doParallelLimit(fn) {
  292. return function (obj, limit, iterator, callback) {
  293. return fn(_eachOfLimit(limit), obj, iterator, callback);
  294. };
  295. }
  296. function doSeries(fn) {
  297. return function (obj, iterator, callback) {
  298. return fn(async.eachOfSeries, obj, iterator, callback);
  299. };
  300. }
  301. function _asyncMap(eachfn, arr, iterator, callback) {
  302. callback = _once(callback || noop);
  303. arr = arr || [];
  304. var results = _isArrayLike(arr) ? [] : {};
  305. eachfn(arr, function (value, index, callback) {
  306. iterator(value, function (err, v) {
  307. results[index] = v;
  308. callback(err);
  309. });
  310. }, function (err) {
  311. callback(err, results);
  312. });
  313. }
  314. async.map = doParallel(_asyncMap);
  315. async.mapSeries = doSeries(_asyncMap);
  316. async.mapLimit = doParallelLimit(_asyncMap);
  317. // reduce only has a series version, as doing reduce in parallel won't
  318. // work in many situations.
  319. async.inject =
  320. async.foldl =
  321. async.reduce = function (arr, memo, iterator, callback) {
  322. async.eachOfSeries(arr, function (x, i, callback) {
  323. iterator(memo, x, function (err, v) {
  324. memo = v;
  325. callback(err);
  326. });
  327. }, function (err) {
  328. callback(err, memo);
  329. });
  330. };
  331. async.foldr =
  332. async.reduceRight = function (arr, memo, iterator, callback) {
  333. var reversed = _map(arr, identity).reverse();
  334. async.reduce(reversed, memo, iterator, callback);
  335. };
  336. async.transform = function (arr, memo, iterator, callback) {
  337. if (arguments.length === 3) {
  338. callback = iterator;
  339. iterator = memo;
  340. memo = _isArray(arr) ? [] : {};
  341. }
  342. async.eachOf(arr, function(v, k, cb) {
  343. iterator(memo, v, k, cb);
  344. }, function(err) {
  345. callback(err, memo);
  346. });
  347. };
  348. function _filter(eachfn, arr, iterator, callback) {
  349. var results = [];
  350. eachfn(arr, function (x, index, callback) {
  351. iterator(x, function (v) {
  352. if (v) {
  353. results.push({index: index, value: x});
  354. }
  355. callback();
  356. });
  357. }, function () {
  358. callback(_map(results.sort(function (a, b) {
  359. return a.index - b.index;
  360. }), function (x) {
  361. return x.value;
  362. }));
  363. });
  364. }
  365. async.select =
  366. async.filter = doParallel(_filter);
  367. async.selectLimit =
  368. async.filterLimit = doParallelLimit(_filter);
  369. async.selectSeries =
  370. async.filterSeries = doSeries(_filter);
  371. function _reject(eachfn, arr, iterator, callback) {
  372. _filter(eachfn, arr, function(value, cb) {
  373. iterator(value, function(v) {
  374. cb(!v);
  375. });
  376. }, callback);
  377. }
  378. async.reject = doParallel(_reject);
  379. async.rejectLimit = doParallelLimit(_reject);
  380. async.rejectSeries = doSeries(_reject);
  381. function _createTester(eachfn, check, getResult) {
  382. return function(arr, limit, iterator, cb) {
  383. function done() {
  384. if (cb) cb(getResult(false, void 0));
  385. }
  386. function iteratee(x, _, callback) {
  387. if (!cb) return callback();
  388. iterator(x, function (v) {
  389. if (cb && check(v)) {
  390. cb(getResult(true, x));
  391. cb = iterator = false;
  392. }
  393. callback();
  394. });
  395. }
  396. if (arguments.length > 3) {
  397. eachfn(arr, limit, iteratee, done);
  398. } else {
  399. cb = iterator;
  400. iterator = limit;
  401. eachfn(arr, iteratee, done);
  402. }
  403. };
  404. }
  405. async.any =
  406. async.some = _createTester(async.eachOf, toBool, identity);
  407. async.someLimit = _createTester(async.eachOfLimit, toBool, identity);
  408. async.all =
  409. async.every = _createTester(async.eachOf, notId, notId);
  410. async.everyLimit = _createTester(async.eachOfLimit, notId, notId);
  411. function _findGetResult(v, x) {
  412. return x;
  413. }
  414. async.detect = _createTester(async.eachOf, identity, _findGetResult);
  415. async.detectSeries = _createTester(async.eachOfSeries, identity, _findGetResult);
  416. async.detectLimit = _createTester(async.eachOfLimit, identity, _findGetResult);
  417. async.sortBy = function (arr, iterator, callback) {
  418. async.map(arr, function (x, callback) {
  419. iterator(x, function (err, criteria) {
  420. if (err) {
  421. callback(err);
  422. }
  423. else {
  424. callback(null, {value: x, criteria: criteria});
  425. }
  426. });
  427. }, function (err, results) {
  428. if (err) {
  429. return callback(err);
  430. }
  431. else {
  432. callback(null, _map(results.sort(comparator), function (x) {
  433. return x.value;
  434. }));
  435. }
  436. });
  437. function comparator(left, right) {
  438. var a = left.criteria, b = right.criteria;
  439. return a < b ? -1 : a > b ? 1 : 0;
  440. }
  441. };
  442. async.auto = function (tasks, concurrency, callback) {
  443. if (typeof arguments[1] === 'function') {
  444. // concurrency is optional, shift the args.
  445. callback = concurrency;
  446. concurrency = null;
  447. }
  448. callback = _once(callback || noop);
  449. var keys = _keys(tasks);
  450. var remainingTasks = keys.length;
  451. if (!remainingTasks) {
  452. return callback(null);
  453. }
  454. if (!concurrency) {
  455. concurrency = remainingTasks;
  456. }
  457. var results = {};
  458. var runningTasks = 0;
  459. var hasError = false;
  460. var listeners = [];
  461. function addListener(fn) {
  462. listeners.unshift(fn);
  463. }
  464. function removeListener(fn) {
  465. var idx = _indexOf(listeners, fn);
  466. if (idx >= 0) listeners.splice(idx, 1);
  467. }
  468. function taskComplete() {
  469. remainingTasks--;
  470. _arrayEach(listeners.slice(0), function (fn) {
  471. fn();
  472. });
  473. }
  474. addListener(function () {
  475. if (!remainingTasks) {
  476. callback(null, results);
  477. }
  478. });
  479. _arrayEach(keys, function (k) {
  480. if (hasError) return;
  481. var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]];
  482. var taskCallback = _restParam(function(err, args) {
  483. runningTasks--;
  484. if (args.length <= 1) {
  485. args = args[0];
  486. }
  487. if (err) {
  488. var safeResults = {};
  489. _forEachOf(results, function(val, rkey) {
  490. safeResults[rkey] = val;
  491. });
  492. safeResults[k] = args;
  493. hasError = true;
  494. callback(err, safeResults);
  495. }
  496. else {
  497. results[k] = args;
  498. async.setImmediate(taskComplete);
  499. }
  500. });
  501. var requires = task.slice(0, task.length - 1);
  502. // prevent dead-locks
  503. var len = requires.length;
  504. var dep;
  505. while (len--) {
  506. if (!(dep = tasks[requires[len]])) {
  507. throw new Error('Has nonexistent dependency in ' + requires.join(', '));
  508. }
  509. if (_isArray(dep) && _indexOf(dep, k) >= 0) {
  510. throw new Error('Has cyclic dependencies');
  511. }
  512. }
  513. function ready() {
  514. return runningTasks < concurrency && _reduce(requires, function (a, x) {
  515. return (a && results.hasOwnProperty(x));
  516. }, true) && !results.hasOwnProperty(k);
  517. }
  518. if (ready()) {
  519. runningTasks++;
  520. task[task.length - 1](taskCallback, results);
  521. }
  522. else {
  523. addListener(listener);
  524. }
  525. function listener() {
  526. if (ready()) {
  527. runningTasks++;
  528. removeListener(listener);
  529. task[task.length - 1](taskCallback, results);
  530. }
  531. }
  532. });
  533. };
  534. async.retry = function(times, task, callback) {
  535. var DEFAULT_TIMES = 5;
  536. var DEFAULT_INTERVAL = 0;
  537. var attempts = [];
  538. var opts = {
  539. times: DEFAULT_TIMES,
  540. interval: DEFAULT_INTERVAL
  541. };
  542. function parseTimes(acc, t){
  543. if(typeof t === 'number'){
  544. acc.times = parseInt(t, 10) || DEFAULT_TIMES;
  545. } else if(typeof t === 'object'){
  546. acc.times = parseInt(t.times, 10) || DEFAULT_TIMES;
  547. acc.interval = parseInt(t.interval, 10) || DEFAULT_INTERVAL;
  548. } else {
  549. throw new Error('Unsupported argument type for \'times\': ' + typeof t);
  550. }
  551. }
  552. var length = arguments.length;
  553. if (length < 1 || length > 3) {
  554. throw new Error('Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)');
  555. } else if (length <= 2 && typeof times === 'function') {
  556. callback = task;
  557. task = times;
  558. }
  559. if (typeof times !== 'function') {
  560. parseTimes(opts, times);
  561. }
  562. opts.callback = callback;
  563. opts.task = task;
  564. function wrappedTask(wrappedCallback, wrappedResults) {
  565. function retryAttempt(task, finalAttempt) {
  566. return function(seriesCallback) {
  567. task(function(err, result){
  568. seriesCallback(!err || finalAttempt, {err: err, result: result});
  569. }, wrappedResults);
  570. };
  571. }
  572. function retryInterval(interval){
  573. return function(seriesCallback){
  574. setTimeout(function(){
  575. seriesCallback(null);
  576. }, interval);
  577. };
  578. }
  579. while (opts.times) {
  580. var finalAttempt = !(opts.times-=1);
  581. attempts.push(retryAttempt(opts.task, finalAttempt));
  582. if(!finalAttempt && opts.interval > 0){
  583. attempts.push(retryInterval(opts.interval));
  584. }
  585. }
  586. async.series(attempts, function(done, data){
  587. data = data[data.length - 1];
  588. (wrappedCallback || opts.callback)(data.err, data.result);
  589. });
  590. }
  591. // If a callback is passed, run this as a controll flow
  592. return opts.callback ? wrappedTask() : wrappedTask;
  593. };
  594. async.waterfall = function (tasks, callback) {
  595. callback = _once(callback || noop);
  596. if (!_isArray(tasks)) {
  597. var err = new Error('First argument to waterfall must be an array of functions');
  598. return callback(err);
  599. }
  600. if (!tasks.length) {
  601. return callback();
  602. }
  603. function wrapIterator(iterator) {
  604. return _restParam(function (err, args) {
  605. if (err) {
  606. callback.apply(null, [err].concat(args));
  607. }
  608. else {
  609. var next = iterator.next();
  610. if (next) {
  611. args.push(wrapIterator(next));
  612. }
  613. else {
  614. args.push(callback);
  615. }
  616. ensureAsync(iterator).apply(null, args);
  617. }
  618. });
  619. }
  620. wrapIterator(async.iterator(tasks))();
  621. };
  622. function _parallel(eachfn, tasks, callback) {
  623. callback = callback || noop;
  624. var results = _isArrayLike(tasks) ? [] : {};
  625. eachfn(tasks, function (task, key, callback) {
  626. task(_restParam(function (err, args) {
  627. if (args.length <= 1) {
  628. args = args[0];
  629. }
  630. results[key] = args;
  631. callback(err);
  632. }));
  633. }, function (err) {
  634. callback(err, results);
  635. });
  636. }
  637. async.parallel = function (tasks, callback) {
  638. _parallel(async.eachOf, tasks, callback);
  639. };
  640. async.parallelLimit = function(tasks, limit, callback) {
  641. _parallel(_eachOfLimit(limit), tasks, callback);
  642. };
  643. async.series = function(tasks, callback) {
  644. _parallel(async.eachOfSeries, tasks, callback);
  645. };
  646. async.iterator = function (tasks) {
  647. function makeCallback(index) {
  648. function fn() {
  649. if (tasks.length) {
  650. tasks[index].apply(null, arguments);
  651. }
  652. return fn.next();
  653. }
  654. fn.next = function () {
  655. return (index < tasks.length - 1) ? makeCallback(index + 1): null;
  656. };
  657. return fn;
  658. }
  659. return makeCallback(0);
  660. };
  661. async.apply = _restParam(function (fn, args) {
  662. return _restParam(function (callArgs) {
  663. return fn.apply(
  664. null, args.concat(callArgs)
  665. );
  666. });
  667. });
  668. function _concat(eachfn, arr, fn, callback) {
  669. var result = [];
  670. eachfn(arr, function (x, index, cb) {
  671. fn(x, function (err, y) {
  672. result = result.concat(y || []);
  673. cb(err);
  674. });
  675. }, function (err) {
  676. callback(err, result);
  677. });
  678. }
  679. async.concat = doParallel(_concat);
  680. async.concatSeries = doSeries(_concat);
  681. async.whilst = function (test, iterator, callback) {
  682. callback = callback || noop;
  683. if (test()) {
  684. var next = _restParam(function(err, args) {
  685. if (err) {
  686. callback(err);
  687. } else if (test.apply(this, args)) {
  688. iterator(next);
  689. } else {
  690. callback.apply(null, [null].concat(args));
  691. }
  692. });
  693. iterator(next);
  694. } else {
  695. callback(null);
  696. }
  697. };
  698. async.doWhilst = function (iterator, test, callback) {
  699. var calls = 0;
  700. return async.whilst(function() {
  701. return ++calls <= 1 || test.apply(this, arguments);
  702. }, iterator, callback);
  703. };
  704. async.until = function (test, iterator, callback) {
  705. return async.whilst(function() {
  706. return !test.apply(this, arguments);
  707. }, iterator, callback);
  708. };
  709. async.doUntil = function (iterator, test, callback) {
  710. return async.doWhilst(iterator, function() {
  711. return !test.apply(this, arguments);
  712. }, callback);
  713. };
  714. async.during = function (test, iterator, callback) {
  715. callback = callback || noop;
  716. var next = _restParam(function(err, args) {
  717. if (err) {
  718. callback(err);
  719. } else {
  720. args.push(check);
  721. test.apply(this, args);
  722. }
  723. });
  724. var check = function(err, truth) {
  725. if (err) {
  726. callback(err);
  727. } else if (truth) {
  728. iterator(next);
  729. } else {
  730. callback(null);
  731. }
  732. };
  733. test(check);
  734. };
  735. async.doDuring = function (iterator, test, callback) {
  736. var calls = 0;
  737. async.during(function(next) {
  738. if (calls++ < 1) {
  739. next(null, true);
  740. } else {
  741. test.apply(this, arguments);
  742. }
  743. }, iterator, callback);
  744. };
  745. function _queue(worker, concurrency, payload) {
  746. if (concurrency == null) {
  747. concurrency = 1;
  748. }
  749. else if(concurrency === 0) {
  750. throw new Error('Concurrency must not be zero');
  751. }
  752. function _insert(q, data, pos, callback) {
  753. if (callback != null && typeof callback !== "function") {
  754. throw new Error("task callback must be a function");
  755. }
  756. q.started = true;
  757. if (!_isArray(data)) {
  758. data = [data];
  759. }
  760. if(data.length === 0 && q.idle()) {
  761. // call drain immediately if there are no tasks
  762. return async.setImmediate(function() {
  763. q.drain();
  764. });
  765. }
  766. _arrayEach(data, function(task) {
  767. var item = {
  768. data: task,
  769. callback: callback || noop
  770. };
  771. if (pos) {
  772. q.tasks.unshift(item);
  773. } else {
  774. q.tasks.push(item);
  775. }
  776. if (q.tasks.length === q.concurrency) {
  777. q.saturated();
  778. }
  779. });
  780. async.setImmediate(q.process);
  781. }
  782. function _next(q, tasks) {
  783. return function(){
  784. workers -= 1;
  785. var removed = false;
  786. var args = arguments;
  787. _arrayEach(tasks, function (task) {
  788. _arrayEach(workersList, function (worker, index) {
  789. if (worker === task && !removed) {
  790. workersList.splice(index, 1);
  791. removed = true;
  792. }
  793. });
  794. task.callback.apply(task, args);
  795. });
  796. if (q.tasks.length + workers === 0) {
  797. q.drain();
  798. }
  799. q.process();
  800. };
  801. }
  802. var workers = 0;
  803. var workersList = [];
  804. var q = {
  805. tasks: [],
  806. concurrency: concurrency,
  807. payload: payload,
  808. saturated: noop,
  809. empty: noop,
  810. drain: noop,
  811. started: false,
  812. paused: false,
  813. push: function (data, callback) {
  814. _insert(q, data, false, callback);
  815. },
  816. kill: function () {
  817. q.drain = noop;
  818. q.tasks = [];
  819. },
  820. unshift: function (data, callback) {
  821. _insert(q, data, true, callback);
  822. },
  823. process: function () {
  824. while(!q.paused && workers < q.concurrency && q.tasks.length){
  825. var tasks = q.payload ?
  826. q.tasks.splice(0, q.payload) :
  827. q.tasks.splice(0, q.tasks.length);
  828. var data = _map(tasks, function (task) {
  829. return task.data;
  830. });
  831. if (q.tasks.length === 0) {
  832. q.empty();
  833. }
  834. workers += 1;
  835. workersList.push(tasks[0]);
  836. var cb = only_once(_next(q, tasks));
  837. worker(data, cb);
  838. }
  839. },
  840. length: function () {
  841. return q.tasks.length;
  842. },
  843. running: function () {
  844. return workers;
  845. },
  846. workersList: function () {
  847. return workersList;
  848. },
  849. idle: function() {
  850. return q.tasks.length + workers === 0;
  851. },
  852. pause: function () {
  853. q.paused = true;
  854. },
  855. resume: function () {
  856. if (q.paused === false) { return; }
  857. q.paused = false;
  858. var resumeCount = Math.min(q.concurrency, q.tasks.length);
  859. // Need to call q.process once per concurrent
  860. // worker to preserve full concurrency after pause
  861. for (var w = 1; w <= resumeCount; w++) {
  862. async.setImmediate(q.process);
  863. }
  864. }
  865. };
  866. return q;
  867. }
  868. async.queue = function (worker, concurrency) {
  869. var q = _queue(function (items, cb) {
  870. worker(items[0], cb);
  871. }, concurrency, 1);
  872. return q;
  873. };
  874. async.priorityQueue = function (worker, concurrency) {
  875. function _compareTasks(a, b){
  876. return a.priority - b.priority;
  877. }
  878. function _binarySearch(sequence, item, compare) {
  879. var beg = -1,
  880. end = sequence.length - 1;
  881. while (beg < end) {
  882. var mid = beg + ((end - beg + 1) >>> 1);
  883. if (compare(item, sequence[mid]) >= 0) {
  884. beg = mid;
  885. } else {
  886. end = mid - 1;
  887. }
  888. }
  889. return beg;
  890. }
  891. function _insert(q, data, priority, callback) {
  892. if (callback != null && typeof callback !== "function") {
  893. throw new Error("task callback must be a function");
  894. }
  895. q.started = true;
  896. if (!_isArray(data)) {
  897. data = [data];
  898. }
  899. if(data.length === 0) {
  900. // call drain immediately if there are no tasks
  901. return async.setImmediate(function() {
  902. q.drain();
  903. });
  904. }
  905. _arrayEach(data, function(task) {
  906. var item = {
  907. data: task,
  908. priority: priority,
  909. callback: typeof callback === 'function' ? callback : noop
  910. };
  911. q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);
  912. if (q.tasks.length === q.concurrency) {
  913. q.saturated();
  914. }
  915. async.setImmediate(q.process);
  916. });
  917. }
  918. // Start with a normal queue
  919. var q = async.queue(worker, concurrency);
  920. // Override push to accept second parameter representing priority
  921. q.push = function (data, priority, callback) {
  922. _insert(q, data, priority, callback);
  923. };
  924. // Remove unshift function
  925. delete q.unshift;
  926. return q;
  927. };
  928. async.cargo = function (worker, payload) {
  929. return _queue(worker, 1, payload);
  930. };
  931. function _console_fn(name) {
  932. return _restParam(function (fn, args) {
  933. fn.apply(null, args.concat([_restParam(function (err, args) {
  934. if (typeof console === 'object') {
  935. if (err) {
  936. if (console.error) {
  937. console.error(err);
  938. }
  939. }
  940. else if (console[name]) {
  941. _arrayEach(args, function (x) {
  942. console[name](x);
  943. });
  944. }
  945. }
  946. })]));
  947. });
  948. }
  949. async.log = _console_fn('log');
  950. async.dir = _console_fn('dir');
  951. /*async.info = _console_fn('info');
  952. async.warn = _console_fn('warn');
  953. async.error = _console_fn('error');*/
  954. async.memoize = function (fn, hasher) {
  955. var memo = {};
  956. var queues = {};
  957. var has = Object.prototype.hasOwnProperty;
  958. hasher = hasher || identity;
  959. var memoized = _restParam(function memoized(args) {
  960. var callback = args.pop();
  961. var key = hasher.apply(null, args);
  962. if (has.call(memo, key)) {
  963. async.setImmediate(function () {
  964. callback.apply(null, memo[key]);
  965. });
  966. }
  967. else if (has.call(queues, key)) {
  968. queues[key].push(callback);
  969. }
  970. else {
  971. queues[key] = [callback];
  972. fn.apply(null, args.concat([_restParam(function (args) {
  973. memo[key] = args;
  974. var q = queues[key];
  975. delete queues[key];
  976. for (var i = 0, l = q.length; i < l; i++) {
  977. q[i].apply(null, args);
  978. }
  979. })]));
  980. }
  981. });
  982. memoized.memo = memo;
  983. memoized.unmemoized = fn;
  984. return memoized;
  985. };
  986. async.unmemoize = function (fn) {
  987. return function () {
  988. return (fn.unmemoized || fn).apply(null, arguments);
  989. };
  990. };
  991. function _times(mapper) {
  992. return function (count, iterator, callback) {
  993. mapper(_range(count), iterator, callback);
  994. };
  995. }
  996. async.times = _times(async.map);
  997. async.timesSeries = _times(async.mapSeries);
  998. async.timesLimit = function (count, limit, iterator, callback) {
  999. return async.mapLimit(_range(count), limit, iterator, callback);
  1000. };
  1001. async.seq = function (/* functions... */) {
  1002. var fns = arguments;
  1003. return _restParam(function (args) {
  1004. var that = this;
  1005. var callback = args[args.length - 1];
  1006. if (typeof callback == 'function') {
  1007. args.pop();
  1008. } else {
  1009. callback = noop;
  1010. }
  1011. async.reduce(fns, args, function (newargs, fn, cb) {
  1012. fn.apply(that, newargs.concat([_restParam(function (err, nextargs) {
  1013. cb(err, nextargs);
  1014. })]));
  1015. },
  1016. function (err, results) {
  1017. callback.apply(that, [err].concat(results));
  1018. });
  1019. });
  1020. };
  1021. async.compose = function (/* functions... */) {
  1022. return async.seq.apply(null, Array.prototype.reverse.call(arguments));
  1023. };
  1024. function _applyEach(eachfn) {
  1025. return _restParam(function(fns, args) {
  1026. var go = _restParam(function(args) {
  1027. var that = this;
  1028. var callback = args.pop();
  1029. return eachfn(fns, function (fn, _, cb) {
  1030. fn.apply(that, args.concat([cb]));
  1031. },
  1032. callback);
  1033. });
  1034. if (args.length) {
  1035. return go.apply(this, args);
  1036. }
  1037. else {
  1038. return go;
  1039. }
  1040. });
  1041. }
  1042. async.applyEach = _applyEach(async.eachOf);
  1043. async.applyEachSeries = _applyEach(async.eachOfSeries);
  1044. async.forever = function (fn, callback) {
  1045. var done = only_once(callback || noop);
  1046. var task = ensureAsync(fn);
  1047. function next(err) {
  1048. if (err) {
  1049. return done(err);
  1050. }
  1051. task(next);
  1052. }
  1053. next();
  1054. };
  1055. function ensureAsync(fn) {
  1056. return _restParam(function (args) {
  1057. var callback = args.pop();
  1058. args.push(function () {
  1059. var innerArgs = arguments;
  1060. if (sync) {
  1061. async.setImmediate(function () {
  1062. callback.apply(null, innerArgs);
  1063. });
  1064. } else {
  1065. callback.apply(null, innerArgs);
  1066. }
  1067. });
  1068. var sync = true;
  1069. fn.apply(this, args);
  1070. sync = false;
  1071. });
  1072. }
  1073. async.ensureAsync = ensureAsync;
  1074. async.constant = _restParam(function(values) {
  1075. var args = [null].concat(values);
  1076. return function (callback) {
  1077. return callback.apply(this, args);
  1078. };
  1079. });
  1080. async.wrapSync =
  1081. async.asyncify = function asyncify(func) {
  1082. return _restParam(function (args) {
  1083. var callback = args.pop();
  1084. var result;
  1085. try {
  1086. result = func.apply(this, args);
  1087. } catch (e) {
  1088. return callback(e);
  1089. }
  1090. // if result is Promise object
  1091. if (_isObject(result) && typeof result.then === "function") {
  1092. result.then(function(value) {
  1093. callback(null, value);
  1094. })["catch"](function(err) {
  1095. callback(err.message ? err : new Error(err));
  1096. });
  1097. } else {
  1098. callback(null, result);
  1099. }
  1100. });
  1101. };
  1102. // Node.js
  1103. if (typeof module === 'object' && module.exports) {
  1104. module.exports = async;
  1105. }
  1106. // AMD / RequireJS
  1107. else if (typeof define === 'function' && define.amd) {
  1108. define([], function () {
  1109. return async;
  1110. });
  1111. }
  1112. // included directly via <script> tag
  1113. else {
  1114. root.async = async;
  1115. }
  1116. }());