Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

async.js 32KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058
  1. /*!
  2. * async
  3. * https://github.com/caolan/async
  4. *
  5. * Copyright 2010-2014 Caolan McMahon
  6. * Released under the MIT license
  7. */
  8. /*jshint onevar: false, indent:4 */
  9. /*global setImmediate: false, setTimeout: false, console: false */
  10. (function () {
  11. var async = {};
  12. // global on the server, window in the browser
  13. var root, previous_async;
  14. root = this;
  15. if (root != null) {
  16. previous_async = root.async;
  17. }
  18. async.noConflict = function () {
  19. root.async = previous_async;
  20. return async;
  21. };
  22. function only_once(fn) {
  23. var called = false;
  24. return function() {
  25. if (called) throw new Error("Callback was already called.");
  26. called = true;
  27. fn.apply(root, arguments);
  28. }
  29. }
  30. //// cross-browser compatiblity functions ////
  31. var _toString = Object.prototype.toString;
  32. var _isArray = Array.isArray || function (obj) {
  33. return _toString.call(obj) === '[object Array]';
  34. };
  35. var _each = function (arr, iterator) {
  36. if (arr.forEach) {
  37. return arr.forEach(iterator);
  38. }
  39. for (var i = 0; i < arr.length; i += 1) {
  40. iterator(arr[i], i, arr);
  41. }
  42. };
  43. var _map = function (arr, iterator) {
  44. if (arr.map) {
  45. return arr.map(iterator);
  46. }
  47. var results = [];
  48. _each(arr, function (x, i, a) {
  49. results.push(iterator(x, i, a));
  50. });
  51. return results;
  52. };
  53. var _reduce = function (arr, iterator, memo) {
  54. if (arr.reduce) {
  55. return arr.reduce(iterator, memo);
  56. }
  57. _each(arr, function (x, i, a) {
  58. memo = iterator(memo, x, i, a);
  59. });
  60. return memo;
  61. };
  62. var _keys = function (obj) {
  63. if (Object.keys) {
  64. return Object.keys(obj);
  65. }
  66. var keys = [];
  67. for (var k in obj) {
  68. if (obj.hasOwnProperty(k)) {
  69. keys.push(k);
  70. }
  71. }
  72. return keys;
  73. };
  74. //// exported async module functions ////
  75. //// nextTick implementation with browser-compatible fallback ////
  76. if (typeof process === 'undefined' || !(process.nextTick)) {
  77. if (typeof setImmediate === 'function') {
  78. async.nextTick = function (fn) {
  79. // not a direct alias for IE10 compatibility
  80. setImmediate(fn);
  81. };
  82. async.setImmediate = async.nextTick;
  83. }
  84. else {
  85. async.nextTick = function (fn) {
  86. setTimeout(fn, 0);
  87. };
  88. async.setImmediate = async.nextTick;
  89. }
  90. }
  91. else {
  92. async.nextTick = process.nextTick;
  93. if (typeof setImmediate !== 'undefined') {
  94. async.setImmediate = function (fn) {
  95. // not a direct alias for IE10 compatibility
  96. setImmediate(fn);
  97. };
  98. }
  99. else {
  100. async.setImmediate = async.nextTick;
  101. }
  102. }
  103. async.each = function (arr, iterator, callback) {
  104. callback = callback || function () {};
  105. if (!arr.length) {
  106. return callback();
  107. }
  108. var completed = 0;
  109. _each(arr, function (x) {
  110. iterator(x, only_once(done) );
  111. });
  112. function done(err) {
  113. if (err) {
  114. callback(err);
  115. callback = function () {};
  116. }
  117. else {
  118. completed += 1;
  119. if (completed >= arr.length) {
  120. callback();
  121. }
  122. }
  123. }
  124. };
  125. async.forEach = async.each;
  126. async.eachSeries = function (arr, iterator, callback) {
  127. callback = callback || function () {};
  128. if (!arr.length) {
  129. return callback();
  130. }
  131. var completed = 0;
  132. var iterate = function () {
  133. iterator(arr[completed], function (err) {
  134. if (err) {
  135. callback(err);
  136. callback = function () {};
  137. }
  138. else {
  139. completed += 1;
  140. if (completed >= arr.length) {
  141. callback();
  142. }
  143. else {
  144. iterate();
  145. }
  146. }
  147. });
  148. };
  149. iterate();
  150. };
  151. async.forEachSeries = async.eachSeries;
  152. async.eachLimit = function (arr, limit, iterator, callback) {
  153. var fn = _eachLimit(limit);
  154. fn.apply(null, [arr, iterator, callback]);
  155. };
  156. async.forEachLimit = async.eachLimit;
  157. var _eachLimit = function (limit) {
  158. return function (arr, iterator, callback) {
  159. callback = callback || function () {};
  160. if (!arr.length || limit <= 0) {
  161. return callback();
  162. }
  163. var completed = 0;
  164. var started = 0;
  165. var running = 0;
  166. (function replenish () {
  167. if (completed >= arr.length) {
  168. return callback();
  169. }
  170. while (running < limit && started < arr.length) {
  171. started += 1;
  172. running += 1;
  173. iterator(arr[started - 1], function (err) {
  174. if (err) {
  175. callback(err);
  176. callback = function () {};
  177. }
  178. else {
  179. completed += 1;
  180. running -= 1;
  181. if (completed >= arr.length) {
  182. callback();
  183. }
  184. else {
  185. replenish();
  186. }
  187. }
  188. });
  189. }
  190. })();
  191. };
  192. };
  193. var doParallel = function (fn) {
  194. return function () {
  195. var args = Array.prototype.slice.call(arguments);
  196. return fn.apply(null, [async.each].concat(args));
  197. };
  198. };
  199. var doParallelLimit = function(limit, fn) {
  200. return function () {
  201. var args = Array.prototype.slice.call(arguments);
  202. return fn.apply(null, [_eachLimit(limit)].concat(args));
  203. };
  204. };
  205. var doSeries = function (fn) {
  206. return function () {
  207. var args = Array.prototype.slice.call(arguments);
  208. return fn.apply(null, [async.eachSeries].concat(args));
  209. };
  210. };
  211. var _asyncMap = function (eachfn, arr, iterator, callback) {
  212. arr = _map(arr, function (x, i) {
  213. return {index: i, value: x};
  214. });
  215. if (!callback) {
  216. eachfn(arr, function (x, callback) {
  217. iterator(x.value, function (err) {
  218. callback(err);
  219. });
  220. });
  221. } else {
  222. var results = [];
  223. eachfn(arr, function (x, callback) {
  224. iterator(x.value, function (err, v) {
  225. results[x.index] = v;
  226. callback(err);
  227. });
  228. }, function (err) {
  229. callback(err, results);
  230. });
  231. }
  232. };
  233. async.map = doParallel(_asyncMap);
  234. async.mapSeries = doSeries(_asyncMap);
  235. async.mapLimit = function (arr, limit, iterator, callback) {
  236. return _mapLimit(limit)(arr, iterator, callback);
  237. };
  238. var _mapLimit = function(limit) {
  239. return doParallelLimit(limit, _asyncMap);
  240. };
  241. // reduce only has a series version, as doing reduce in parallel won't
  242. // work in many situations.
  243. async.reduce = function (arr, memo, iterator, callback) {
  244. async.eachSeries(arr, function (x, callback) {
  245. iterator(memo, x, function (err, v) {
  246. memo = v;
  247. callback(err);
  248. });
  249. }, function (err) {
  250. callback(err, memo);
  251. });
  252. };
  253. // inject alias
  254. async.inject = async.reduce;
  255. // foldl alias
  256. async.foldl = async.reduce;
  257. async.reduceRight = function (arr, memo, iterator, callback) {
  258. var reversed = _map(arr, function (x) {
  259. return x;
  260. }).reverse();
  261. async.reduce(reversed, memo, iterator, callback);
  262. };
  263. // foldr alias
  264. async.foldr = async.reduceRight;
  265. var _filter = function (eachfn, arr, iterator, callback) {
  266. var results = [];
  267. arr = _map(arr, function (x, i) {
  268. return {index: i, value: x};
  269. });
  270. eachfn(arr, function (x, callback) {
  271. iterator(x.value, function (v) {
  272. if (v) {
  273. results.push(x);
  274. }
  275. callback();
  276. });
  277. }, function (err) {
  278. callback(_map(results.sort(function (a, b) {
  279. return a.index - b.index;
  280. }), function (x) {
  281. return x.value;
  282. }));
  283. });
  284. };
  285. async.filter = doParallel(_filter);
  286. async.filterSeries = doSeries(_filter);
  287. // select alias
  288. async.select = async.filter;
  289. async.selectSeries = async.filterSeries;
  290. var _reject = function (eachfn, arr, iterator, callback) {
  291. var results = [];
  292. arr = _map(arr, function (x, i) {
  293. return {index: i, value: x};
  294. });
  295. eachfn(arr, function (x, callback) {
  296. iterator(x.value, function (v) {
  297. if (!v) {
  298. results.push(x);
  299. }
  300. callback();
  301. });
  302. }, function (err) {
  303. callback(_map(results.sort(function (a, b) {
  304. return a.index - b.index;
  305. }), function (x) {
  306. return x.value;
  307. }));
  308. });
  309. };
  310. async.reject = doParallel(_reject);
  311. async.rejectSeries = doSeries(_reject);
  312. var _detect = function (eachfn, arr, iterator, main_callback) {
  313. eachfn(arr, function (x, callback) {
  314. iterator(x, function (result) {
  315. if (result) {
  316. main_callback(x);
  317. main_callback = function () {};
  318. }
  319. else {
  320. callback();
  321. }
  322. });
  323. }, function (err) {
  324. main_callback();
  325. });
  326. };
  327. async.detect = doParallel(_detect);
  328. async.detectSeries = doSeries(_detect);
  329. async.some = function (arr, iterator, main_callback) {
  330. async.each(arr, function (x, callback) {
  331. iterator(x, function (v) {
  332. if (v) {
  333. main_callback(true);
  334. main_callback = function () {};
  335. }
  336. callback();
  337. });
  338. }, function (err) {
  339. main_callback(false);
  340. });
  341. };
  342. // any alias
  343. async.any = async.some;
  344. async.every = function (arr, iterator, main_callback) {
  345. async.each(arr, function (x, callback) {
  346. iterator(x, function (v) {
  347. if (!v) {
  348. main_callback(false);
  349. main_callback = function () {};
  350. }
  351. callback();
  352. });
  353. }, function (err) {
  354. main_callback(true);
  355. });
  356. };
  357. // all alias
  358. async.all = async.every;
  359. async.sortBy = function (arr, iterator, callback) {
  360. async.map(arr, function (x, callback) {
  361. iterator(x, function (err, criteria) {
  362. if (err) {
  363. callback(err);
  364. }
  365. else {
  366. callback(null, {value: x, criteria: criteria});
  367. }
  368. });
  369. }, function (err, results) {
  370. if (err) {
  371. return callback(err);
  372. }
  373. else {
  374. var fn = function (left, right) {
  375. var a = left.criteria, b = right.criteria;
  376. return a < b ? -1 : a > b ? 1 : 0;
  377. };
  378. callback(null, _map(results.sort(fn), function (x) {
  379. return x.value;
  380. }));
  381. }
  382. });
  383. };
  384. async.auto = function (tasks, callback) {
  385. callback = callback || function () {};
  386. var keys = _keys(tasks);
  387. var remainingTasks = keys.length
  388. if (!remainingTasks) {
  389. return callback();
  390. }
  391. var results = {};
  392. var listeners = [];
  393. var addListener = function (fn) {
  394. listeners.unshift(fn);
  395. };
  396. var removeListener = function (fn) {
  397. for (var i = 0; i < listeners.length; i += 1) {
  398. if (listeners[i] === fn) {
  399. listeners.splice(i, 1);
  400. return;
  401. }
  402. }
  403. };
  404. var taskComplete = function () {
  405. remainingTasks--
  406. _each(listeners.slice(0), function (fn) {
  407. fn();
  408. });
  409. };
  410. addListener(function () {
  411. if (!remainingTasks) {
  412. var theCallback = callback;
  413. // prevent final callback from calling itself if it errors
  414. callback = function () {};
  415. theCallback(null, results);
  416. }
  417. });
  418. _each(keys, function (k) {
  419. var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]];
  420. var taskCallback = function (err) {
  421. var args = Array.prototype.slice.call(arguments, 1);
  422. if (args.length <= 1) {
  423. args = args[0];
  424. }
  425. if (err) {
  426. var safeResults = {};
  427. _each(_keys(results), function(rkey) {
  428. safeResults[rkey] = results[rkey];
  429. });
  430. safeResults[k] = args;
  431. callback(err, safeResults);
  432. // stop subsequent errors hitting callback multiple times
  433. callback = function () {};
  434. }
  435. else {
  436. results[k] = args;
  437. async.setImmediate(taskComplete);
  438. }
  439. };
  440. var requires = task.slice(0, Math.abs(task.length - 1)) || [];
  441. var ready = function () {
  442. return _reduce(requires, function (a, x) {
  443. return (a && results.hasOwnProperty(x));
  444. }, true) && !results.hasOwnProperty(k);
  445. };
  446. if (ready()) {
  447. task[task.length - 1](taskCallback, results);
  448. }
  449. else {
  450. var listener = function () {
  451. if (ready()) {
  452. removeListener(listener);
  453. task[task.length - 1](taskCallback, results);
  454. }
  455. };
  456. addListener(listener);
  457. }
  458. });
  459. };
  460. async.retry = function(times, task, callback) {
  461. var DEFAULT_TIMES = 5;
  462. var attempts = [];
  463. // Use defaults if times not passed
  464. if (typeof times === 'function') {
  465. callback = task;
  466. task = times;
  467. times = DEFAULT_TIMES;
  468. }
  469. // Make sure times is a number
  470. times = parseInt(times, 10) || DEFAULT_TIMES;
  471. var wrappedTask = function(wrappedCallback, wrappedResults) {
  472. var retryAttempt = function(task, finalAttempt) {
  473. return function(seriesCallback) {
  474. task(function(err, result){
  475. seriesCallback(!err || finalAttempt, {err: err, result: result});
  476. }, wrappedResults);
  477. };
  478. };
  479. while (times) {
  480. attempts.push(retryAttempt(task, !(times-=1)));
  481. }
  482. async.series(attempts, function(done, data){
  483. data = data[data.length - 1];
  484. (wrappedCallback || callback)(data.err, data.result);
  485. });
  486. }
  487. // If a callback is passed, run this as a controll flow
  488. return callback ? wrappedTask() : wrappedTask
  489. };
  490. async.waterfall = function (tasks, callback) {
  491. callback = callback || function () {};
  492. if (!_isArray(tasks)) {
  493. var err = new Error('First argument to waterfall must be an array of functions');
  494. return callback(err);
  495. }
  496. if (!tasks.length) {
  497. return callback();
  498. }
  499. var wrapIterator = function (iterator) {
  500. return function (err) {
  501. if (err) {
  502. callback.apply(null, arguments);
  503. callback = function () {};
  504. }
  505. else {
  506. var args = Array.prototype.slice.call(arguments, 1);
  507. var next = iterator.next();
  508. if (next) {
  509. args.push(wrapIterator(next));
  510. }
  511. else {
  512. args.push(callback);
  513. }
  514. async.setImmediate(function () {
  515. iterator.apply(null, args);
  516. });
  517. }
  518. };
  519. };
  520. wrapIterator(async.iterator(tasks))();
  521. };
  522. var _parallel = function(eachfn, tasks, callback) {
  523. callback = callback || function () {};
  524. if (_isArray(tasks)) {
  525. eachfn.map(tasks, function (fn, callback) {
  526. if (fn) {
  527. fn(function (err) {
  528. var args = Array.prototype.slice.call(arguments, 1);
  529. if (args.length <= 1) {
  530. args = args[0];
  531. }
  532. callback.call(null, err, args);
  533. });
  534. }
  535. }, callback);
  536. }
  537. else {
  538. var results = {};
  539. eachfn.each(_keys(tasks), function (k, callback) {
  540. tasks[k](function (err) {
  541. var args = Array.prototype.slice.call(arguments, 1);
  542. if (args.length <= 1) {
  543. args = args[0];
  544. }
  545. results[k] = args;
  546. callback(err);
  547. });
  548. }, function (err) {
  549. callback(err, results);
  550. });
  551. }
  552. };
  553. async.parallel = function (tasks, callback) {
  554. _parallel({ map: async.map, each: async.each }, tasks, callback);
  555. };
  556. async.parallelLimit = function(tasks, limit, callback) {
  557. _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback);
  558. };
  559. async.series = function (tasks, callback) {
  560. callback = callback || function () {};
  561. if (_isArray(tasks)) {
  562. async.mapSeries(tasks, function (fn, callback) {
  563. if (fn) {
  564. fn(function (err) {
  565. var args = Array.prototype.slice.call(arguments, 1);
  566. if (args.length <= 1) {
  567. args = args[0];
  568. }
  569. callback.call(null, err, args);
  570. });
  571. }
  572. }, callback);
  573. }
  574. else {
  575. var results = {};
  576. async.eachSeries(_keys(tasks), function (k, callback) {
  577. tasks[k](function (err) {
  578. var args = Array.prototype.slice.call(arguments, 1);
  579. if (args.length <= 1) {
  580. args = args[0];
  581. }
  582. results[k] = args;
  583. callback(err);
  584. });
  585. }, function (err) {
  586. callback(err, results);
  587. });
  588. }
  589. };
  590. async.iterator = function (tasks) {
  591. var makeCallback = function (index) {
  592. var fn = function () {
  593. if (tasks.length) {
  594. tasks[index].apply(null, arguments);
  595. }
  596. return fn.next();
  597. };
  598. fn.next = function () {
  599. return (index < tasks.length - 1) ? makeCallback(index + 1): null;
  600. };
  601. return fn;
  602. };
  603. return makeCallback(0);
  604. };
  605. async.apply = function (fn) {
  606. var args = Array.prototype.slice.call(arguments, 1);
  607. return function () {
  608. return fn.apply(
  609. null, args.concat(Array.prototype.slice.call(arguments))
  610. );
  611. };
  612. };
  613. var _concat = function (eachfn, arr, fn, callback) {
  614. var r = [];
  615. eachfn(arr, function (x, cb) {
  616. fn(x, function (err, y) {
  617. r = r.concat(y || []);
  618. cb(err);
  619. });
  620. }, function (err) {
  621. callback(err, r);
  622. });
  623. };
  624. async.concat = doParallel(_concat);
  625. async.concatSeries = doSeries(_concat);
  626. async.whilst = function (test, iterator, callback) {
  627. if (test()) {
  628. iterator(function (err) {
  629. if (err) {
  630. return callback(err);
  631. }
  632. async.whilst(test, iterator, callback);
  633. });
  634. }
  635. else {
  636. callback();
  637. }
  638. };
  639. async.doWhilst = function (iterator, test, callback) {
  640. iterator(function (err) {
  641. if (err) {
  642. return callback(err);
  643. }
  644. var args = Array.prototype.slice.call(arguments, 1);
  645. if (test.apply(null, args)) {
  646. async.doWhilst(iterator, test, callback);
  647. }
  648. else {
  649. callback();
  650. }
  651. });
  652. };
  653. async.until = function (test, iterator, callback) {
  654. if (!test()) {
  655. iterator(function (err) {
  656. if (err) {
  657. return callback(err);
  658. }
  659. async.until(test, iterator, callback);
  660. });
  661. }
  662. else {
  663. callback();
  664. }
  665. };
  666. async.doUntil = function (iterator, test, callback) {
  667. iterator(function (err) {
  668. if (err) {
  669. return callback(err);
  670. }
  671. var args = Array.prototype.slice.call(arguments, 1);
  672. if (!test.apply(null, args)) {
  673. async.doUntil(iterator, test, callback);
  674. }
  675. else {
  676. callback();
  677. }
  678. });
  679. };
  680. async.queue = function (worker, concurrency) {
  681. if (concurrency === undefined) {
  682. concurrency = 1;
  683. }
  684. function _insert(q, data, pos, callback) {
  685. if (!q.started){
  686. q.started = true;
  687. }
  688. if (!_isArray(data)) {
  689. data = [data];
  690. }
  691. if(data.length == 0) {
  692. // call drain immediately if there are no tasks
  693. return async.setImmediate(function() {
  694. if (q.drain) {
  695. q.drain();
  696. }
  697. });
  698. }
  699. _each(data, function(task) {
  700. var item = {
  701. data: task,
  702. callback: typeof callback === 'function' ? callback : null
  703. };
  704. if (pos) {
  705. q.tasks.unshift(item);
  706. } else {
  707. q.tasks.push(item);
  708. }
  709. if (q.saturated && q.tasks.length === q.concurrency) {
  710. q.saturated();
  711. }
  712. async.setImmediate(q.process);
  713. });
  714. }
  715. var workers = 0;
  716. var q = {
  717. tasks: [],
  718. concurrency: concurrency,
  719. saturated: null,
  720. empty: null,
  721. drain: null,
  722. started: false,
  723. paused: false,
  724. push: function (data, callback) {
  725. _insert(q, data, false, callback);
  726. },
  727. kill: function () {
  728. q.drain = null;
  729. q.tasks = [];
  730. },
  731. unshift: function (data, callback) {
  732. _insert(q, data, true, callback);
  733. },
  734. process: function () {
  735. if (!q.paused && workers < q.concurrency && q.tasks.length) {
  736. var task = q.tasks.shift();
  737. if (q.empty && q.tasks.length === 0) {
  738. q.empty();
  739. }
  740. workers += 1;
  741. var next = function () {
  742. workers -= 1;
  743. if (task.callback) {
  744. task.callback.apply(task, arguments);
  745. }
  746. if (q.drain && q.tasks.length + workers === 0) {
  747. q.drain();
  748. }
  749. q.process();
  750. };
  751. var cb = only_once(next);
  752. worker(task.data, cb);
  753. }
  754. },
  755. length: function () {
  756. return q.tasks.length;
  757. },
  758. running: function () {
  759. return workers;
  760. },
  761. idle: function() {
  762. return q.tasks.length + workers === 0;
  763. },
  764. pause: function () {
  765. if (q.paused === true) { return; }
  766. q.paused = true;
  767. q.process();
  768. },
  769. resume: function () {
  770. if (q.paused === false) { return; }
  771. q.paused = false;
  772. q.process();
  773. }
  774. };
  775. return q;
  776. };
  777. async.cargo = function (worker, payload) {
  778. var working = false,
  779. tasks = [];
  780. var cargo = {
  781. tasks: tasks,
  782. payload: payload,
  783. saturated: null,
  784. empty: null,
  785. drain: null,
  786. drained: true,
  787. push: function (data, callback) {
  788. if (!_isArray(data)) {
  789. data = [data];
  790. }
  791. _each(data, function(task) {
  792. tasks.push({
  793. data: task,
  794. callback: typeof callback === 'function' ? callback : null
  795. });
  796. cargo.drained = false;
  797. if (cargo.saturated && tasks.length === payload) {
  798. cargo.saturated();
  799. }
  800. });
  801. async.setImmediate(cargo.process);
  802. },
  803. process: function process() {
  804. if (working) return;
  805. if (tasks.length === 0) {
  806. if(cargo.drain && !cargo.drained) cargo.drain();
  807. cargo.drained = true;
  808. return;
  809. }
  810. var ts = typeof payload === 'number'
  811. ? tasks.splice(0, payload)
  812. : tasks.splice(0, tasks.length);
  813. var ds = _map(ts, function (task) {
  814. return task.data;
  815. });
  816. if(cargo.empty) cargo.empty();
  817. working = true;
  818. worker(ds, function () {
  819. working = false;
  820. var args = arguments;
  821. _each(ts, function (data) {
  822. if (data.callback) {
  823. data.callback.apply(null, args);
  824. }
  825. });
  826. process();
  827. });
  828. },
  829. length: function () {
  830. return tasks.length;
  831. },
  832. running: function () {
  833. return working;
  834. }
  835. };
  836. return cargo;
  837. };
  838. var _console_fn = function (name) {
  839. return function (fn) {
  840. var args = Array.prototype.slice.call(arguments, 1);
  841. fn.apply(null, args.concat([function (err) {
  842. var args = Array.prototype.slice.call(arguments, 1);
  843. if (typeof console !== 'undefined') {
  844. if (err) {
  845. if (console.error) {
  846. console.error(err);
  847. }
  848. }
  849. else if (console[name]) {
  850. _each(args, function (x) {
  851. console[name](x);
  852. });
  853. }
  854. }
  855. }]));
  856. };
  857. };
  858. async.log = _console_fn('log');
  859. async.dir = _console_fn('dir');
  860. /*async.info = _console_fn('info');
  861. async.warn = _console_fn('warn');
  862. async.error = _console_fn('error');*/
  863. async.memoize = function (fn, hasher) {
  864. var memo = {};
  865. var queues = {};
  866. hasher = hasher || function (x) {
  867. return x;
  868. };
  869. var memoized = function () {
  870. var args = Array.prototype.slice.call(arguments);
  871. var callback = args.pop();
  872. var key = hasher.apply(null, args);
  873. if (key in memo) {
  874. async.nextTick(function () {
  875. callback.apply(null, memo[key]);
  876. });
  877. }
  878. else if (key in queues) {
  879. queues[key].push(callback);
  880. }
  881. else {
  882. queues[key] = [callback];
  883. fn.apply(null, args.concat([function () {
  884. memo[key] = arguments;
  885. var q = queues[key];
  886. delete queues[key];
  887. for (var i = 0, l = q.length; i < l; i++) {
  888. q[i].apply(null, arguments);
  889. }
  890. }]));
  891. }
  892. };
  893. memoized.memo = memo;
  894. memoized.unmemoized = fn;
  895. return memoized;
  896. };
  897. async.unmemoize = function (fn) {
  898. return function () {
  899. return (fn.unmemoized || fn).apply(null, arguments);
  900. };
  901. };
  902. async.times = function (count, iterator, callback) {
  903. var counter = [];
  904. for (var i = 0; i < count; i++) {
  905. counter.push(i);
  906. }
  907. return async.map(counter, iterator, callback);
  908. };
  909. async.timesSeries = function (count, iterator, callback) {
  910. var counter = [];
  911. for (var i = 0; i < count; i++) {
  912. counter.push(i);
  913. }
  914. return async.mapSeries(counter, iterator, callback);
  915. };
  916. async.seq = function (/* functions... */) {
  917. var fns = arguments;
  918. return function () {
  919. var that = this;
  920. var args = Array.prototype.slice.call(arguments);
  921. var callback = args.pop();
  922. async.reduce(fns, args, function (newargs, fn, cb) {
  923. fn.apply(that, newargs.concat([function () {
  924. var err = arguments[0];
  925. var nextargs = Array.prototype.slice.call(arguments, 1);
  926. cb(err, nextargs);
  927. }]))
  928. },
  929. function (err, results) {
  930. callback.apply(that, [err].concat(results));
  931. });
  932. };
  933. };
  934. async.compose = function (/* functions... */) {
  935. return async.seq.apply(null, Array.prototype.reverse.call(arguments));
  936. };
  937. var _applyEach = function (eachfn, fns /*args...*/) {
  938. var go = function () {
  939. var that = this;
  940. var args = Array.prototype.slice.call(arguments);
  941. var callback = args.pop();
  942. return eachfn(fns, function (fn, cb) {
  943. fn.apply(that, args.concat([cb]));
  944. },
  945. callback);
  946. };
  947. if (arguments.length > 2) {
  948. var args = Array.prototype.slice.call(arguments, 2);
  949. return go.apply(this, args);
  950. }
  951. else {
  952. return go;
  953. }
  954. };
  955. async.applyEach = doParallel(_applyEach);
  956. async.applyEachSeries = doSeries(_applyEach);
  957. async.forever = function (fn, callback) {
  958. function next(err) {
  959. if (err) {
  960. if (callback) {
  961. return callback(err);
  962. }
  963. throw err;
  964. }
  965. fn(next);
  966. }
  967. next();
  968. };
  969. // Node.js
  970. if (typeof module !== 'undefined' && module.exports) {
  971. module.exports = async;
  972. }
  973. // AMD / RequireJS
  974. else if (typeof define !== 'undefined' && define.amd) {
  975. define([], function () {
  976. return async;
  977. });
  978. }
  979. // included directly via <script> tag
  980. else {
  981. root.async = async;
  982. }
  983. }());