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