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