Source: dependencies/resource-loader/lib/async.js

dependencies/resource-loader/lib/async.js

  1. 'use strict';
  2. exports.__esModule = true;
  3. exports.eachSeries = eachSeries;
  4. exports.queue = queue;
  5. /**
  6. * Smaller version of the async library constructs.
  7. *
  8. * @namespace async
  9. */
  10. /**
  11. * Noop function
  12. *
  13. * @ignore
  14. * @function
  15. * @memberof async
  16. */
  17. function _noop() {} /* empty */
  18. /**
  19. * Iterates an array in series.
  20. *
  21. * @memberof async
  22. * @param {Array.<*>} array - Array to iterate.
  23. * @param {function} iterator - Function to call for each element.
  24. * @param {function} callback - Function to call when done, or on error.
  25. * @param {boolean} [deferNext=false] - Break synchronous each loop by calling next with a setTimeout of 1.
  26. */
  27. function eachSeries(array, iterator, callback, deferNext) {
  28. var i = 0;
  29. var len = array.length;
  30. (function next(err) {
  31. if (err || i === len) {
  32. if (callback) {
  33. callback(err);
  34. }
  35. return;
  36. }
  37. if (deferNext) {
  38. setTimeout(function () {
  39. iterator(array[i++], next);
  40. }, 1);
  41. } else {
  42. iterator(array[i++], next);
  43. }
  44. })();
  45. }
  46. /**
  47. * Ensures a function is only called once.
  48. *
  49. * @ignore
  50. * @memberof async
  51. * @param {function} fn - The function to wrap.
  52. * @return {function} The wrapping function.
  53. */
  54. function onlyOnce(fn) {
  55. return function onceWrapper() {
  56. if (fn === null) {
  57. throw new Error('Callback was already called.');
  58. }
  59. var callFn = fn;
  60. fn = null;
  61. callFn.apply(this, arguments);
  62. };
  63. }
  64. /**
  65. * Async queue implementation,
  66. *
  67. * @memberof async
  68. * @param {function} worker - The worker function to call for each task.
  69. * @param {number} concurrency - How many workers to run in parrallel.
  70. * @return {*} The async queue object.
  71. */
  72. function queue(worker, concurrency) {
  73. if (concurrency == null) {
  74. // eslint-disable-line no-eq-null,eqeqeq
  75. concurrency = 1;
  76. } else if (concurrency === 0) {
  77. throw new Error('Concurrency must not be zero');
  78. }
  79. var workers = 0;
  80. var q = {
  81. _tasks: [],
  82. concurrency: concurrency,
  83. saturated: _noop,
  84. unsaturated: _noop,
  85. buffer: concurrency / 4,
  86. empty: _noop,
  87. drain: _noop,
  88. error: _noop,
  89. started: false,
  90. paused: false,
  91. push: function push(data, callback) {
  92. _insert(data, false, callback);
  93. },
  94. kill: function kill() {
  95. workers = 0;
  96. q.drain = _noop;
  97. q.started = false;
  98. q._tasks = [];
  99. },
  100. unshift: function unshift(data, callback) {
  101. _insert(data, true, callback);
  102. },
  103. process: function process() {
  104. while (!q.paused && workers < q.concurrency && q._tasks.length) {
  105. var task = q._tasks.shift();
  106. if (q._tasks.length === 0) {
  107. q.empty();
  108. }
  109. workers += 1;
  110. if (workers === q.concurrency) {
  111. q.saturated();
  112. }
  113. worker(task.data, onlyOnce(_next(task)));
  114. }
  115. },
  116. length: function length() {
  117. return q._tasks.length;
  118. },
  119. running: function running() {
  120. return workers;
  121. },
  122. idle: function idle() {
  123. return q._tasks.length + workers === 0;
  124. },
  125. pause: function pause() {
  126. if (q.paused === true) {
  127. return;
  128. }
  129. q.paused = true;
  130. },
  131. resume: function resume() {
  132. if (q.paused === false) {
  133. return;
  134. }
  135. q.paused = false;
  136. // Need to call q.process once per concurrent
  137. // worker to preserve full concurrency after pause
  138. for (var w = 1; w <= q.concurrency; w++) {
  139. q.process();
  140. }
  141. }
  142. };
  143. function _insert(data, insertAtFront, callback) {
  144. if (callback != null && typeof callback !== 'function') {
  145. // eslint-disable-line no-eq-null,eqeqeq
  146. throw new Error('task callback must be a function');
  147. }
  148. q.started = true;
  149. if (data == null && q.idle()) {
  150. // eslint-disable-line no-eq-null,eqeqeq
  151. // call drain immediately if there are no tasks
  152. setTimeout(function () {
  153. return q.drain();
  154. }, 1);
  155. return;
  156. }
  157. var item = {
  158. data: data,
  159. callback: typeof callback === 'function' ? callback : _noop
  160. };
  161. if (insertAtFront) {
  162. q._tasks.unshift(item);
  163. } else {
  164. q._tasks.push(item);
  165. }
  166. setTimeout(function () {
  167. return q.process();
  168. }, 1);
  169. }
  170. function _next(task) {
  171. return function next() {
  172. workers -= 1;
  173. task.callback.apply(task, arguments);
  174. if (arguments[0] != null) {
  175. // eslint-disable-line no-eq-null,eqeqeq
  176. q.error(arguments[0], task.data);
  177. }
  178. if (workers <= q.concurrency - q.buffer) {
  179. q.unsaturated();
  180. }
  181. if (q.idle()) {
  182. q.drain();
  183. }
  184. q.process();
  185. };
  186. }
  187. return q;
  188. }
  189. //# sourceMappingURL=async.js.map