1 |
|
2 | (function () {
|
3 |
|
4 | var async = {};
|
5 |
|
6 |
|
7 | var root = this,
|
8 | previous_async = root.async;
|
9 |
|
10 | async.noConflict = function () {
|
11 | root.async = previous_async;
|
12 | return async;
|
13 | };
|
14 |
|
15 |
|
16 |
|
17 | var _forEach = function (arr, iterator) {
|
18 | if (arr.forEach) {
|
19 | return arr.forEach(iterator);
|
20 | }
|
21 | for (var i = 0; i < arr.length; i += 1) {
|
22 | iterator(arr[i], i, arr);
|
23 | }
|
24 | };
|
25 |
|
26 | var _map = function (arr, iterator) {
|
27 | if (arr.map) {
|
28 | return arr.map(iterator);
|
29 | }
|
30 | var results = [];
|
31 | _forEach(arr, function (x, i, a) {
|
32 | results.push(iterator(x, i, a));
|
33 | });
|
34 | return results;
|
35 | };
|
36 |
|
37 | var _reduce = function (arr, iterator, memo) {
|
38 | if (arr.reduce) {
|
39 | return arr.reduce(iterator, memo);
|
40 | }
|
41 | _forEach(arr, function (x, i, a) {
|
42 | memo = iterator(memo, x, i, a);
|
43 | });
|
44 | return memo;
|
45 | };
|
46 |
|
47 | var _keys = function (obj) {
|
48 | if (Object.keys) {
|
49 | return Object.keys(obj);
|
50 | }
|
51 | var keys = [];
|
52 | for (var k in obj) {
|
53 | if (obj.hasOwnProperty(k)) {
|
54 | keys.push(k);
|
55 | }
|
56 | }
|
57 | return keys;
|
58 | };
|
59 |
|
60 |
|
61 |
|
62 |
|
63 | if (typeof process === 'undefined' || !(process.nextTick)) {
|
64 | async.nextTick = function (fn) {
|
65 | setTimeout(fn, 0);
|
66 | };
|
67 | }
|
68 | else {
|
69 | async.nextTick = process.nextTick;
|
70 | }
|
71 |
|
72 | async.forEach = function (arr, iterator, callback) {
|
73 | callback = callback || function () {};
|
74 | if (!arr.length) {
|
75 | return callback();
|
76 | }
|
77 | var completed = 0;
|
78 | _forEach(arr, function (x) {
|
79 | iterator(x, function (err) {
|
80 | if (err) {
|
81 | callback(err);
|
82 | callback = function () {};
|
83 | }
|
84 | else {
|
85 | completed += 1;
|
86 | if (completed === arr.length) {
|
87 | callback(null);
|
88 | }
|
89 | }
|
90 | });
|
91 | });
|
92 | };
|
93 |
|
94 | async.forEachSeries = function (arr, iterator, callback) {
|
95 | callback = callback || function () {};
|
96 | if (!arr.length) {
|
97 | return callback();
|
98 | }
|
99 | var completed = 0;
|
100 | var iterate = function () {
|
101 | iterator(arr[completed], function (err) {
|
102 | if (err) {
|
103 | callback(err);
|
104 | callback = function () {};
|
105 | }
|
106 | else {
|
107 | completed += 1;
|
108 | if (completed === arr.length) {
|
109 | callback(null);
|
110 | }
|
111 | else {
|
112 | iterate();
|
113 | }
|
114 | }
|
115 | });
|
116 | };
|
117 | iterate();
|
118 | };
|
119 |
|
120 | async.forEachLimit = function (arr, limit, iterator, callback) {
|
121 | callback = callback || function () {};
|
122 | if (!arr.length || limit <= 0) {
|
123 | return callback();
|
124 | }
|
125 | var completed = 0;
|
126 | var started = 0;
|
127 | var running = 0;
|
128 |
|
129 | (function replenish () {
|
130 | if (completed === arr.length) {
|
131 | return callback();
|
132 | }
|
133 |
|
134 | while (running < limit && started < arr.length) {
|
135 | started += 1;
|
136 | running += 1;
|
137 | iterator(arr[started - 1], function (err) {
|
138 | if (err) {
|
139 | callback(err);
|
140 | callback = function () {};
|
141 | }
|
142 | else {
|
143 | completed += 1;
|
144 | running -= 1;
|
145 | if (completed === arr.length) {
|
146 | callback();
|
147 | }
|
148 | else {
|
149 | replenish();
|
150 | }
|
151 | }
|
152 | });
|
153 | }
|
154 | })();
|
155 | };
|
156 |
|
157 |
|
158 | var doParallel = function (fn) {
|
159 | return function () {
|
160 | var args = Array.prototype.slice.call(arguments);
|
161 | return fn.apply(null, [async.forEach].concat(args));
|
162 | };
|
163 | };
|
164 | var doSeries = function (fn) {
|
165 | return function () {
|
166 | var args = Array.prototype.slice.call(arguments);
|
167 | return fn.apply(null, [async.forEachSeries].concat(args));
|
168 | };
|
169 | };
|
170 |
|
171 |
|
172 | var _asyncMap = function (eachfn, arr, iterator, callback) {
|
173 | var results = [];
|
174 | arr = _map(arr, function (x, i) {
|
175 | return {index: i, value: x};
|
176 | });
|
177 | eachfn(arr, function (x, callback) {
|
178 | iterator(x.value, function (err, v) {
|
179 | results[x.index] = v;
|
180 | callback(err);
|
181 | });
|
182 | }, function (err) {
|
183 | callback(err, results);
|
184 | });
|
185 | };
|
186 | async.map = doParallel(_asyncMap);
|
187 | async.mapSeries = doSeries(_asyncMap);
|
188 |
|
189 |
|
190 |
|
191 |
|
192 | async.reduce = function (arr, memo, iterator, callback) {
|
193 | async.forEachSeries(arr, function (x, callback) {
|
194 | iterator(memo, x, function (err, v) {
|
195 | memo = v;
|
196 | callback(err);
|
197 | });
|
198 | }, function (err) {
|
199 | callback(err, memo);
|
200 | });
|
201 | };
|
202 |
|
203 | async.inject = async.reduce;
|
204 |
|
205 | async.foldl = async.reduce;
|
206 |
|
207 | async.reduceRight = function (arr, memo, iterator, callback) {
|
208 | var reversed = _map(arr, function (x) {
|
209 | return x;
|
210 | }).reverse();
|
211 | async.reduce(reversed, memo, iterator, callback);
|
212 | };
|
213 |
|
214 | async.foldr = async.reduceRight;
|
215 |
|
216 | var _filter = function (eachfn, arr, iterator, callback) {
|
217 | var results = [];
|
218 | arr = _map(arr, function (x, i) {
|
219 | return {index: i, value: x};
|
220 | });
|
221 | eachfn(arr, function (x, callback) {
|
222 | iterator(x.value, function (v) {
|
223 | if (v) {
|
224 | results.push(x);
|
225 | }
|
226 | callback();
|
227 | });
|
228 | }, function (err) {
|
229 | callback(_map(results.sort(function (a, b) {
|
230 | return a.index - b.index;
|
231 | }), function (x) {
|
232 | return x.value;
|
233 | }));
|
234 | });
|
235 | };
|
236 | async.filter = doParallel(_filter);
|
237 | async.filterSeries = doSeries(_filter);
|
238 |
|
239 | async.select = async.filter;
|
240 | async.selectSeries = async.filterSeries;
|
241 |
|
242 | var _reject = function (eachfn, arr, iterator, callback) {
|
243 | var results = [];
|
244 | arr = _map(arr, function (x, i) {
|
245 | return {index: i, value: x};
|
246 | });
|
247 | eachfn(arr, function (x, callback) {
|
248 | iterator(x.value, function (v) {
|
249 | if (!v) {
|
250 | results.push(x);
|
251 | }
|
252 | callback();
|
253 | });
|
254 | }, function (err) {
|
255 | callback(_map(results.sort(function (a, b) {
|
256 | return a.index - b.index;
|
257 | }), function (x) {
|
258 | return x.value;
|
259 | }));
|
260 | });
|
261 | };
|
262 | async.reject = doParallel(_reject);
|
263 | async.rejectSeries = doSeries(_reject);
|
264 |
|
265 | var _detect = function (eachfn, arr, iterator, main_callback) {
|
266 | eachfn(arr, function (x, callback) {
|
267 | iterator(x, function (result) {
|
268 | if (result) {
|
269 | main_callback(x);
|
270 | main_callback = function () {};
|
271 | }
|
272 | else {
|
273 | callback();
|
274 | }
|
275 | });
|
276 | }, function (err) {
|
277 | main_callback();
|
278 | });
|
279 | };
|
280 | async.detect = doParallel(_detect);
|
281 | async.detectSeries = doSeries(_detect);
|
282 |
|
283 | async.some = function (arr, iterator, main_callback) {
|
284 | async.forEach(arr, function (x, callback) {
|
285 | iterator(x, function (v) {
|
286 | if (v) {
|
287 | main_callback(true);
|
288 | main_callback = function () {};
|
289 | }
|
290 | callback();
|
291 | });
|
292 | }, function (err) {
|
293 | main_callback(false);
|
294 | });
|
295 | };
|
296 |
|
297 | async.any = async.some;
|
298 |
|
299 | async.every = function (arr, iterator, main_callback) {
|
300 | async.forEach(arr, function (x, callback) {
|
301 | iterator(x, function (v) {
|
302 | if (!v) {
|
303 | main_callback(false);
|
304 | main_callback = function () {};
|
305 | }
|
306 | callback();
|
307 | });
|
308 | }, function (err) {
|
309 | main_callback(true);
|
310 | });
|
311 | };
|
312 |
|
313 | async.all = async.every;
|
314 |
|
315 | async.sortBy = function (arr, iterator, callback) {
|
316 | async.map(arr, function (x, callback) {
|
317 | iterator(x, function (err, criteria) {
|
318 | if (err) {
|
319 | callback(err);
|
320 | }
|
321 | else {
|
322 | callback(null, {value: x, criteria: criteria});
|
323 | }
|
324 | });
|
325 | }, function (err, results) {
|
326 | if (err) {
|
327 | return callback(err);
|
328 | }
|
329 | else {
|
330 | var fn = function (left, right) {
|
331 | var a = left.criteria, b = right.criteria;
|
332 | return a < b ? -1 : a > b ? 1 : 0;
|
333 | };
|
334 | callback(null, _map(results.sort(fn), function (x) {
|
335 | return x.value;
|
336 | }));
|
337 | }
|
338 | });
|
339 | };
|
340 |
|
341 | async.auto = function (tasks, callback) {
|
342 | callback = callback || function () {};
|
343 | var keys = _keys(tasks);
|
344 | if (!keys.length) {
|
345 | return callback(null);
|
346 | }
|
347 |
|
348 | var results = {};
|
349 |
|
350 | var listeners = [];
|
351 | var addListener = function (fn) {
|
352 | listeners.unshift(fn);
|
353 | };
|
354 | var removeListener = function (fn) {
|
355 | for (var i = 0; i < listeners.length; i += 1) {
|
356 | if (listeners[i] === fn) {
|
357 | listeners.splice(i, 1);
|
358 | return;
|
359 | }
|
360 | }
|
361 | };
|
362 | var taskComplete = function () {
|
363 | _forEach(listeners.slice(0), function (fn) {
|
364 | fn();
|
365 | });
|
366 | };
|
367 |
|
368 | addListener(function () {
|
369 | if (_keys(results).length === keys.length) {
|
370 | callback(null, results);
|
371 | callback = function () {};
|
372 | }
|
373 | });
|
374 |
|
375 | _forEach(keys, function (k) {
|
376 | var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k];
|
377 | var taskCallback = function (err) {
|
378 | if (err) {
|
379 | callback(err);
|
380 |
|
381 | callback = function () {};
|
382 | }
|
383 | else {
|
384 | var args = Array.prototype.slice.call(arguments, 1);
|
385 | if (args.length <= 1) {
|
386 | args = args[0];
|
387 | }
|
388 | results[k] = args;
|
389 | taskComplete();
|
390 | }
|
391 | };
|
392 | var requires = task.slice(0, Math.abs(task.length - 1)) || [];
|
393 | var ready = function () {
|
394 | return _reduce(requires, function (a, x) {
|
395 | return (a && results.hasOwnProperty(x));
|
396 | }, true) && !results.hasOwnProperty(k);
|
397 | };
|
398 | if (ready()) {
|
399 | task[task.length - 1](taskCallback, results);
|
400 | }
|
401 | else {
|
402 | var listener = function () {
|
403 | if (ready()) {
|
404 | removeListener(listener);
|
405 | task[task.length - 1](taskCallback, results);
|
406 | }
|
407 | };
|
408 | addListener(listener);
|
409 | }
|
410 | });
|
411 | };
|
412 |
|
413 | async.waterfall = function (tasks, callback) {
|
414 | callback = callback || function () {};
|
415 | if (!tasks.length) {
|
416 | return callback();
|
417 | }
|
418 | var wrapIterator = function (iterator) {
|
419 | return function (err) {
|
420 | if (err) {
|
421 | callback(err);
|
422 | callback = function () {};
|
423 | }
|
424 | else {
|
425 | var args = Array.prototype.slice.call(arguments, 1);
|
426 | var next = iterator.next();
|
427 | if (next) {
|
428 | args.push(wrapIterator(next));
|
429 | }
|
430 | else {
|
431 | args.push(callback);
|
432 | }
|
433 | async.nextTick(function () {
|
434 | iterator.apply(null, args);
|
435 | });
|
436 | }
|
437 | };
|
438 | };
|
439 | wrapIterator(async.iterator(tasks))();
|
440 | };
|
441 |
|
442 | async.parallel = function (tasks, callback) {
|
443 | callback = callback || function () {};
|
444 | if (tasks.constructor === Array) {
|
445 | async.map(tasks, function (fn, callback) {
|
446 | if (fn) {
|
447 | fn(function (err) {
|
448 | var args = Array.prototype.slice.call(arguments, 1);
|
449 | if (args.length <= 1) {
|
450 | args = args[0];
|
451 | }
|
452 | callback.call(null, err, args);
|
453 | });
|
454 | }
|
455 | }, callback);
|
456 | }
|
457 | else {
|
458 | var results = {};
|
459 | async.forEach(_keys(tasks), function (k, callback) {
|
460 | tasks[k](function (err) {
|
461 | var args = Array.prototype.slice.call(arguments, 1);
|
462 | if (args.length <= 1) {
|
463 | args = args[0];
|
464 | }
|
465 | results[k] = args;
|
466 | callback(err);
|
467 | });
|
468 | }, function (err) {
|
469 | callback(err, results);
|
470 | });
|
471 | }
|
472 | };
|
473 |
|
474 | async.series = function (tasks, callback) {
|
475 | callback = callback || function () {};
|
476 | if (tasks.constructor === Array) {
|
477 | async.mapSeries(tasks, function (fn, callback) {
|
478 | if (fn) {
|
479 | fn(function (err) {
|
480 | var args = Array.prototype.slice.call(arguments, 1);
|
481 | if (args.length <= 1) {
|
482 | args = args[0];
|
483 | }
|
484 | callback.call(null, err, args);
|
485 | });
|
486 | }
|
487 | }, callback);
|
488 | }
|
489 | else {
|
490 | var results = {};
|
491 | async.forEachSeries(_keys(tasks), function (k, callback) {
|
492 | tasks[k](function (err) {
|
493 | var args = Array.prototype.slice.call(arguments, 1);
|
494 | if (args.length <= 1) {
|
495 | args = args[0];
|
496 | }
|
497 | results[k] = args;
|
498 | callback(err);
|
499 | });
|
500 | }, function (err) {
|
501 | callback(err, results);
|
502 | });
|
503 | }
|
504 | };
|
505 |
|
506 | async.iterator = function (tasks) {
|
507 | var makeCallback = function (index) {
|
508 | var fn = function () {
|
509 | if (tasks.length) {
|
510 | tasks[index].apply(null, arguments);
|
511 | }
|
512 | return fn.next();
|
513 | };
|
514 | fn.next = function () {
|
515 | return (index < tasks.length - 1) ? makeCallback(index + 1): null;
|
516 | };
|
517 | return fn;
|
518 | };
|
519 | return makeCallback(0);
|
520 | };
|
521 |
|
522 | async.apply = function (fn) {
|
523 | var args = Array.prototype.slice.call(arguments, 1);
|
524 | return function () {
|
525 | return fn.apply(
|
526 | null, args.concat(Array.prototype.slice.call(arguments))
|
527 | );
|
528 | };
|
529 | };
|
530 |
|
531 | var _concat = function (eachfn, arr, fn, callback) {
|
532 | var r = [];
|
533 | eachfn(arr, function (x, cb) {
|
534 | fn(x, function (err, y) {
|
535 | r = r.concat(y || []);
|
536 | cb(err);
|
537 | });
|
538 | }, function (err) {
|
539 | callback(err, r);
|
540 | });
|
541 | };
|
542 | async.concat = doParallel(_concat);
|
543 | async.concatSeries = doSeries(_concat);
|
544 |
|
545 | async.whilst = function (test, iterator, callback) {
|
546 | if (test()) {
|
547 | iterator(function (err) {
|
548 | if (err) {
|
549 | return callback(err);
|
550 | }
|
551 | async.whilst(test, iterator, callback);
|
552 | });
|
553 | }
|
554 | else {
|
555 | callback();
|
556 | }
|
557 | };
|
558 |
|
559 | async.until = function (test, iterator, callback) {
|
560 | if (!test()) {
|
561 | iterator(function (err) {
|
562 | if (err) {
|
563 | return callback(err);
|
564 | }
|
565 | async.until(test, iterator, callback);
|
566 | });
|
567 | }
|
568 | else {
|
569 | callback();
|
570 | }
|
571 | };
|
572 |
|
573 | async.queue = function (worker, concurrency) {
|
574 | var workers = 0;
|
575 | var q = {
|
576 | tasks: [],
|
577 | concurrency: concurrency,
|
578 | saturated: null,
|
579 | empty: null,
|
580 | drain: null,
|
581 | push: function (data, callback) {
|
582 | if(data.constructor !== Array) {
|
583 | data = [data];
|
584 | }
|
585 | _forEach(data, function(task) {
|
586 | q.tasks.push({
|
587 | data: task,
|
588 | callback: typeof callback === 'function' ? callback : null
|
589 | });
|
590 | if (q.saturated && q.tasks.length == concurrency) {
|
591 | q.saturated();
|
592 | }
|
593 | async.nextTick(q.process);
|
594 | });
|
595 | },
|
596 | process: function () {
|
597 | if (workers < q.concurrency && q.tasks.length) {
|
598 | var task = q.tasks.shift();
|
599 | if(q.empty && q.tasks.length == 0) q.empty();
|
600 | workers += 1;
|
601 | worker(task.data, function () {
|
602 | workers -= 1;
|
603 | if (task.callback) {
|
604 | task.callback.apply(task, arguments);
|
605 | }
|
606 | if(q.drain && q.tasks.length + workers == 0) q.drain();
|
607 | q.process();
|
608 | });
|
609 | }
|
610 | },
|
611 | length: function () {
|
612 | return q.tasks.length;
|
613 | },
|
614 | running: function () {
|
615 | return workers;
|
616 | }
|
617 | };
|
618 | return q;
|
619 | };
|
620 |
|
621 | var _console_fn = function (name) {
|
622 | return function (fn) {
|
623 | var args = Array.prototype.slice.call(arguments, 1);
|
624 | fn.apply(null, args.concat([function (err) {
|
625 | var args = Array.prototype.slice.call(arguments, 1);
|
626 | if (typeof console !== 'undefined') {
|
627 | if (err) {
|
628 | if (console.error) {
|
629 | console.error(err);
|
630 | }
|
631 | }
|
632 | else if (console[name]) {
|
633 | _forEach(args, function (x) {
|
634 | console[name](x);
|
635 | });
|
636 | }
|
637 | }
|
638 | }]));
|
639 | };
|
640 | };
|
641 | async.log = _console_fn('log');
|
642 | async.dir = _console_fn('dir');
|
643 | |
644 |
|
645 |
|
646 |
|
647 | async.memoize = function (fn, hasher) {
|
648 | var memo = {};
|
649 | var queues = {};
|
650 | hasher = hasher || function (x) {
|
651 | return x;
|
652 | };
|
653 | var memoized = function () {
|
654 | var args = Array.prototype.slice.call(arguments);
|
655 | var callback = args.pop();
|
656 | var key = hasher.apply(null, args);
|
657 | if (key in memo) {
|
658 | callback.apply(null, memo[key]);
|
659 | }
|
660 | else if (key in queues) {
|
661 | queues[key].push(callback);
|
662 | }
|
663 | else {
|
664 | queues[key] = [callback];
|
665 | fn.apply(null, args.concat([function () {
|
666 | memo[key] = arguments;
|
667 | var q = queues[key];
|
668 | delete queues[key];
|
669 | for (var i = 0, l = q.length; i < l; i++) {
|
670 | q[i].apply(null, arguments);
|
671 | }
|
672 | }]));
|
673 | }
|
674 | };
|
675 | memoized.unmemoized = fn;
|
676 | return memoized;
|
677 | };
|
678 |
|
679 | async.unmemoize = function (fn) {
|
680 | return function () {
|
681 | return (fn.unmemoized || fn).apply(null, arguments);
|
682 | };
|
683 | };
|
684 |
|
685 |
|
686 | if (typeof define !== 'undefined' && define.amd) {
|
687 | define('async', [], function () {
|
688 | return async;
|
689 | });
|
690 | }
|
691 |
|
692 | else if (typeof module !== 'undefined' && module.exports) {
|
693 | module.exports = async;
|
694 | }
|
695 |
|
696 | else {
|
697 | root.async = async;
|
698 | }
|
699 |
|
700 | }()); |
\ | No newline at end of file |