Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80684 views
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
for (var i = 0; i < arr.length; i += 1) {
46
iterator(arr[i], i, arr);
47
}
48
};
49
50
var _map = function (arr, iterator) {
51
if (arr.map) {
52
return arr.map(iterator);
53
}
54
var results = [];
55
_each(arr, function (x, i, a) {
56
results.push(iterator(x, i, a));
57
});
58
return results;
59
};
60
61
var _reduce = function (arr, iterator, memo) {
62
if (arr.reduce) {
63
return arr.reduce(iterator, memo);
64
}
65
_each(arr, function (x, i, a) {
66
memo = iterator(memo, x, i, a);
67
});
68
return memo;
69
};
70
71
var _keys = function (obj) {
72
if (Object.keys) {
73
return Object.keys(obj);
74
}
75
var keys = [];
76
for (var k in obj) {
77
if (obj.hasOwnProperty(k)) {
78
keys.push(k);
79
}
80
}
81
return keys;
82
};
83
84
//// exported async module functions ////
85
86
//// nextTick implementation with browser-compatible fallback ////
87
if (typeof process === 'undefined' || !(process.nextTick)) {
88
if (typeof setImmediate === 'function') {
89
async.nextTick = function (fn) {
90
// not a direct alias for IE10 compatibility
91
setImmediate(fn);
92
};
93
async.setImmediate = async.nextTick;
94
}
95
else {
96
async.nextTick = function (fn) {
97
setTimeout(fn, 0);
98
};
99
async.setImmediate = async.nextTick;
100
}
101
}
102
else {
103
async.nextTick = process.nextTick;
104
if (typeof setImmediate !== 'undefined') {
105
async.setImmediate = function (fn) {
106
// not a direct alias for IE10 compatibility
107
setImmediate(fn);
108
};
109
}
110
else {
111
async.setImmediate = async.nextTick;
112
}
113
}
114
115
async.each = function (arr, iterator, callback) {
116
callback = callback || function () {};
117
if (!arr.length) {
118
return callback();
119
}
120
var completed = 0;
121
_each(arr, function (x) {
122
iterator(x, only_once(done) );
123
});
124
function done(err) {
125
if (err) {
126
callback(err);
127
callback = function () {};
128
}
129
else {
130
completed += 1;
131
if (completed >= arr.length) {
132
callback();
133
}
134
}
135
}
136
};
137
async.forEach = async.each;
138
139
async.eachSeries = function (arr, iterator, callback) {
140
callback = callback || function () {};
141
if (!arr.length) {
142
return callback();
143
}
144
var completed = 0;
145
var iterate = function () {
146
iterator(arr[completed], function (err) {
147
if (err) {
148
callback(err);
149
callback = function () {};
150
}
151
else {
152
completed += 1;
153
if (completed >= arr.length) {
154
callback();
155
}
156
else {
157
iterate();
158
}
159
}
160
});
161
};
162
iterate();
163
};
164
async.forEachSeries = async.eachSeries;
165
166
async.eachLimit = function (arr, limit, iterator, callback) {
167
var fn = _eachLimit(limit);
168
fn.apply(null, [arr, iterator, callback]);
169
};
170
async.forEachLimit = async.eachLimit;
171
172
var _eachLimit = function (limit) {
173
174
return function (arr, iterator, callback) {
175
callback = callback || function () {};
176
if (!arr.length || limit <= 0) {
177
return callback();
178
}
179
var completed = 0;
180
var started = 0;
181
var running = 0;
182
183
(function replenish () {
184
if (completed >= arr.length) {
185
return callback();
186
}
187
188
while (running < limit && started < arr.length) {
189
started += 1;
190
running += 1;
191
iterator(arr[started - 1], function (err) {
192
if (err) {
193
callback(err);
194
callback = function () {};
195
}
196
else {
197
completed += 1;
198
running -= 1;
199
if (completed >= arr.length) {
200
callback();
201
}
202
else {
203
replenish();
204
}
205
}
206
});
207
}
208
})();
209
};
210
};
211
212
213
var doParallel = function (fn) {
214
return function () {
215
var args = Array.prototype.slice.call(arguments);
216
return fn.apply(null, [async.each].concat(args));
217
};
218
};
219
var doParallelLimit = function(limit, fn) {
220
return function () {
221
var args = Array.prototype.slice.call(arguments);
222
return fn.apply(null, [_eachLimit(limit)].concat(args));
223
};
224
};
225
var doSeries = function (fn) {
226
return function () {
227
var args = Array.prototype.slice.call(arguments);
228
return fn.apply(null, [async.eachSeries].concat(args));
229
};
230
};
231
232
233
var _asyncMap = function (eachfn, arr, iterator, callback) {
234
arr = _map(arr, function (x, i) {
235
return {index: i, value: x};
236
});
237
if (!callback) {
238
eachfn(arr, function (x, callback) {
239
iterator(x.value, function (err) {
240
callback(err);
241
});
242
});
243
} else {
244
var results = [];
245
eachfn(arr, function (x, callback) {
246
iterator(x.value, function (err, v) {
247
results[x.index] = v;
248
callback(err);
249
});
250
}, function (err) {
251
callback(err, results);
252
});
253
}
254
};
255
async.map = doParallel(_asyncMap);
256
async.mapSeries = doSeries(_asyncMap);
257
async.mapLimit = function (arr, limit, iterator, callback) {
258
return _mapLimit(limit)(arr, iterator, callback);
259
};
260
261
var _mapLimit = function(limit) {
262
return doParallelLimit(limit, _asyncMap);
263
};
264
265
// reduce only has a series version, as doing reduce in parallel won't
266
// work in many situations.
267
async.reduce = function (arr, memo, iterator, callback) {
268
async.eachSeries(arr, function (x, callback) {
269
iterator(memo, x, function (err, v) {
270
memo = v;
271
callback(err);
272
});
273
}, function (err) {
274
callback(err, memo);
275
});
276
};
277
// inject alias
278
async.inject = async.reduce;
279
// foldl alias
280
async.foldl = async.reduce;
281
282
async.reduceRight = function (arr, memo, iterator, callback) {
283
var reversed = _map(arr, function (x) {
284
return x;
285
}).reverse();
286
async.reduce(reversed, memo, iterator, callback);
287
};
288
// foldr alias
289
async.foldr = async.reduceRight;
290
291
var _filter = function (eachfn, arr, iterator, callback) {
292
var results = [];
293
arr = _map(arr, function (x, i) {
294
return {index: i, value: x};
295
});
296
eachfn(arr, function (x, callback) {
297
iterator(x.value, function (v) {
298
if (v) {
299
results.push(x);
300
}
301
callback();
302
});
303
}, function (err) {
304
callback(_map(results.sort(function (a, b) {
305
return a.index - b.index;
306
}), function (x) {
307
return x.value;
308
}));
309
});
310
};
311
async.filter = doParallel(_filter);
312
async.filterSeries = doSeries(_filter);
313
// select alias
314
async.select = async.filter;
315
async.selectSeries = async.filterSeries;
316
317
var _reject = function (eachfn, arr, iterator, callback) {
318
var results = [];
319
arr = _map(arr, function (x, i) {
320
return {index: i, value: x};
321
});
322
eachfn(arr, function (x, callback) {
323
iterator(x.value, function (v) {
324
if (!v) {
325
results.push(x);
326
}
327
callback();
328
});
329
}, function (err) {
330
callback(_map(results.sort(function (a, b) {
331
return a.index - b.index;
332
}), function (x) {
333
return x.value;
334
}));
335
});
336
};
337
async.reject = doParallel(_reject);
338
async.rejectSeries = doSeries(_reject);
339
340
var _detect = function (eachfn, arr, iterator, main_callback) {
341
eachfn(arr, function (x, callback) {
342
iterator(x, function (result) {
343
if (result) {
344
main_callback(x);
345
main_callback = function () {};
346
}
347
else {
348
callback();
349
}
350
});
351
}, function (err) {
352
main_callback();
353
});
354
};
355
async.detect = doParallel(_detect);
356
async.detectSeries = doSeries(_detect);
357
358
async.some = function (arr, iterator, main_callback) {
359
async.each(arr, function (x, callback) {
360
iterator(x, function (v) {
361
if (v) {
362
main_callback(true);
363
main_callback = function () {};
364
}
365
callback();
366
});
367
}, function (err) {
368
main_callback(false);
369
});
370
};
371
// any alias
372
async.any = async.some;
373
374
async.every = function (arr, iterator, main_callback) {
375
async.each(arr, function (x, callback) {
376
iterator(x, function (v) {
377
if (!v) {
378
main_callback(false);
379
main_callback = function () {};
380
}
381
callback();
382
});
383
}, function (err) {
384
main_callback(true);
385
});
386
};
387
// all alias
388
async.all = async.every;
389
390
async.sortBy = function (arr, iterator, callback) {
391
async.map(arr, function (x, callback) {
392
iterator(x, function (err, criteria) {
393
if (err) {
394
callback(err);
395
}
396
else {
397
callback(null, {value: x, criteria: criteria});
398
}
399
});
400
}, function (err, results) {
401
if (err) {
402
return callback(err);
403
}
404
else {
405
var fn = function (left, right) {
406
var a = left.criteria, b = right.criteria;
407
return a < b ? -1 : a > b ? 1 : 0;
408
};
409
callback(null, _map(results.sort(fn), function (x) {
410
return x.value;
411
}));
412
}
413
});
414
};
415
416
async.auto = function (tasks, callback) {
417
callback = callback || function () {};
418
var keys = _keys(tasks);
419
var remainingTasks = keys.length
420
if (!remainingTasks) {
421
return callback();
422
}
423
424
var results = {};
425
426
var listeners = [];
427
var addListener = function (fn) {
428
listeners.unshift(fn);
429
};
430
var removeListener = function (fn) {
431
for (var i = 0; i < listeners.length; i += 1) {
432
if (listeners[i] === fn) {
433
listeners.splice(i, 1);
434
return;
435
}
436
}
437
};
438
var taskComplete = function () {
439
remainingTasks--
440
_each(listeners.slice(0), function (fn) {
441
fn();
442
});
443
};
444
445
addListener(function () {
446
if (!remainingTasks) {
447
var theCallback = callback;
448
// prevent final callback from calling itself if it errors
449
callback = function () {};
450
451
theCallback(null, results);
452
}
453
});
454
455
_each(keys, function (k) {
456
var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]];
457
var taskCallback = function (err) {
458
var args = Array.prototype.slice.call(arguments, 1);
459
if (args.length <= 1) {
460
args = args[0];
461
}
462
if (err) {
463
var safeResults = {};
464
_each(_keys(results), function(rkey) {
465
safeResults[rkey] = results[rkey];
466
});
467
safeResults[k] = args;
468
callback(err, safeResults);
469
// stop subsequent errors hitting callback multiple times
470
callback = function () {};
471
}
472
else {
473
results[k] = args;
474
async.setImmediate(taskComplete);
475
}
476
};
477
var requires = task.slice(0, Math.abs(task.length - 1)) || [];
478
var ready = function () {
479
return _reduce(requires, function (a, x) {
480
return (a && results.hasOwnProperty(x));
481
}, true) && !results.hasOwnProperty(k);
482
};
483
if (ready()) {
484
task[task.length - 1](taskCallback, results);
485
}
486
else {
487
var listener = function () {
488
if (ready()) {
489
removeListener(listener);
490
task[task.length - 1](taskCallback, results);
491
}
492
};
493
addListener(listener);
494
}
495
});
496
};
497
498
async.retry = function(times, task, callback) {
499
var DEFAULT_TIMES = 5;
500
var attempts = [];
501
// Use defaults if times not passed
502
if (typeof times === 'function') {
503
callback = task;
504
task = times;
505
times = DEFAULT_TIMES;
506
}
507
// Make sure times is a number
508
times = parseInt(times, 10) || DEFAULT_TIMES;
509
var wrappedTask = function(wrappedCallback, wrappedResults) {
510
var retryAttempt = function(task, finalAttempt) {
511
return function(seriesCallback) {
512
task(function(err, result){
513
seriesCallback(!err || finalAttempt, {err: err, result: result});
514
}, wrappedResults);
515
};
516
};
517
while (times) {
518
attempts.push(retryAttempt(task, !(times-=1)));
519
}
520
async.series(attempts, function(done, data){
521
data = data[data.length - 1];
522
(wrappedCallback || callback)(data.err, data.result);
523
});
524
}
525
// If a callback is passed, run this as a controll flow
526
return callback ? wrappedTask() : wrappedTask
527
};
528
529
async.waterfall = function (tasks, callback) {
530
callback = callback || function () {};
531
if (!_isArray(tasks)) {
532
var err = new Error('First argument to waterfall must be an array of functions');
533
return callback(err);
534
}
535
if (!tasks.length) {
536
return callback();
537
}
538
var wrapIterator = function (iterator) {
539
return function (err) {
540
if (err) {
541
callback.apply(null, arguments);
542
callback = function () {};
543
}
544
else {
545
var args = Array.prototype.slice.call(arguments, 1);
546
var next = iterator.next();
547
if (next) {
548
args.push(wrapIterator(next));
549
}
550
else {
551
args.push(callback);
552
}
553
async.setImmediate(function () {
554
iterator.apply(null, args);
555
});
556
}
557
};
558
};
559
wrapIterator(async.iterator(tasks))();
560
};
561
562
var _parallel = function(eachfn, tasks, callback) {
563
callback = callback || function () {};
564
if (_isArray(tasks)) {
565
eachfn.map(tasks, function (fn, callback) {
566
if (fn) {
567
fn(function (err) {
568
var args = Array.prototype.slice.call(arguments, 1);
569
if (args.length <= 1) {
570
args = args[0];
571
}
572
callback.call(null, err, args);
573
});
574
}
575
}, callback);
576
}
577
else {
578
var results = {};
579
eachfn.each(_keys(tasks), function (k, callback) {
580
tasks[k](function (err) {
581
var args = Array.prototype.slice.call(arguments, 1);
582
if (args.length <= 1) {
583
args = args[0];
584
}
585
results[k] = args;
586
callback(err);
587
});
588
}, function (err) {
589
callback(err, results);
590
});
591
}
592
};
593
594
async.parallel = function (tasks, callback) {
595
_parallel({ map: async.map, each: async.each }, tasks, callback);
596
};
597
598
async.parallelLimit = function(tasks, limit, callback) {
599
_parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback);
600
};
601
602
async.series = function (tasks, callback) {
603
callback = callback || function () {};
604
if (_isArray(tasks)) {
605
async.mapSeries(tasks, function (fn, callback) {
606
if (fn) {
607
fn(function (err) {
608
var args = Array.prototype.slice.call(arguments, 1);
609
if (args.length <= 1) {
610
args = args[0];
611
}
612
callback.call(null, err, args);
613
});
614
}
615
}, callback);
616
}
617
else {
618
var results = {};
619
async.eachSeries(_keys(tasks), function (k, callback) {
620
tasks[k](function (err) {
621
var args = Array.prototype.slice.call(arguments, 1);
622
if (args.length <= 1) {
623
args = args[0];
624
}
625
results[k] = args;
626
callback(err);
627
});
628
}, function (err) {
629
callback(err, results);
630
});
631
}
632
};
633
634
async.iterator = function (tasks) {
635
var makeCallback = function (index) {
636
var fn = function () {
637
if (tasks.length) {
638
tasks[index].apply(null, arguments);
639
}
640
return fn.next();
641
};
642
fn.next = function () {
643
return (index < tasks.length - 1) ? makeCallback(index + 1): null;
644
};
645
return fn;
646
};
647
return makeCallback(0);
648
};
649
650
async.apply = function (fn) {
651
var args = Array.prototype.slice.call(arguments, 1);
652
return function () {
653
return fn.apply(
654
null, args.concat(Array.prototype.slice.call(arguments))
655
);
656
};
657
};
658
659
var _concat = function (eachfn, arr, fn, callback) {
660
var r = [];
661
eachfn(arr, function (x, cb) {
662
fn(x, function (err, y) {
663
r = r.concat(y || []);
664
cb(err);
665
});
666
}, function (err) {
667
callback(err, r);
668
});
669
};
670
async.concat = doParallel(_concat);
671
async.concatSeries = doSeries(_concat);
672
673
async.whilst = function (test, iterator, callback) {
674
if (test()) {
675
iterator(function (err) {
676
if (err) {
677
return callback(err);
678
}
679
async.whilst(test, iterator, callback);
680
});
681
}
682
else {
683
callback();
684
}
685
};
686
687
async.doWhilst = function (iterator, test, callback) {
688
iterator(function (err) {
689
if (err) {
690
return callback(err);
691
}
692
var args = Array.prototype.slice.call(arguments, 1);
693
if (test.apply(null, args)) {
694
async.doWhilst(iterator, test, callback);
695
}
696
else {
697
callback();
698
}
699
});
700
};
701
702
async.until = function (test, iterator, callback) {
703
if (!test()) {
704
iterator(function (err) {
705
if (err) {
706
return callback(err);
707
}
708
async.until(test, iterator, callback);
709
});
710
}
711
else {
712
callback();
713
}
714
};
715
716
async.doUntil = function (iterator, test, callback) {
717
iterator(function (err) {
718
if (err) {
719
return callback(err);
720
}
721
var args = Array.prototype.slice.call(arguments, 1);
722
if (!test.apply(null, args)) {
723
async.doUntil(iterator, test, callback);
724
}
725
else {
726
callback();
727
}
728
});
729
};
730
731
async.queue = function (worker, concurrency) {
732
if (concurrency === undefined) {
733
concurrency = 1;
734
}
735
function _insert(q, data, pos, callback) {
736
if (!q.started){
737
q.started = true;
738
}
739
if (!_isArray(data)) {
740
data = [data];
741
}
742
if(data.length == 0) {
743
// call drain immediately if there are no tasks
744
return async.setImmediate(function() {
745
if (q.drain) {
746
q.drain();
747
}
748
});
749
}
750
_each(data, function(task) {
751
var item = {
752
data: task,
753
callback: typeof callback === 'function' ? callback : null
754
};
755
756
if (pos) {
757
q.tasks.unshift(item);
758
} else {
759
q.tasks.push(item);
760
}
761
762
if (q.saturated && q.tasks.length === q.concurrency) {
763
q.saturated();
764
}
765
async.setImmediate(q.process);
766
});
767
}
768
769
var workers = 0;
770
var q = {
771
tasks: [],
772
concurrency: concurrency,
773
saturated: null,
774
empty: null,
775
drain: null,
776
started: false,
777
paused: false,
778
push: function (data, callback) {
779
_insert(q, data, false, callback);
780
},
781
kill: function () {
782
q.drain = null;
783
q.tasks = [];
784
},
785
unshift: function (data, callback) {
786
_insert(q, data, true, callback);
787
},
788
process: function () {
789
if (!q.paused && workers < q.concurrency && q.tasks.length) {
790
var task = q.tasks.shift();
791
if (q.empty && q.tasks.length === 0) {
792
q.empty();
793
}
794
workers += 1;
795
var next = function () {
796
workers -= 1;
797
if (task.callback) {
798
task.callback.apply(task, arguments);
799
}
800
if (q.drain && q.tasks.length + workers === 0) {
801
q.drain();
802
}
803
q.process();
804
};
805
var cb = only_once(next);
806
worker(task.data, cb);
807
}
808
},
809
length: function () {
810
return q.tasks.length;
811
},
812
running: function () {
813
return workers;
814
},
815
idle: function() {
816
return q.tasks.length + workers === 0;
817
},
818
pause: function () {
819
if (q.paused === true) { return; }
820
q.paused = true;
821
},
822
resume: function () {
823
if (q.paused === false) { return; }
824
q.paused = false;
825
// Need to call q.process once per concurrent
826
// worker to preserve full concurrency after pause
827
for (var w = 1; w <= q.concurrency; w++) {
828
async.setImmediate(q.process);
829
}
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
}());
1124
1125