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