You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

52 lines
1.0 KiB

4 years ago
  1. 'use strict';
  2. const pTry = require('p-try');
  3. const pLimit = concurrency => {
  4. if (!((Number.isInteger(concurrency) || concurrency === Infinity) && concurrency > 0)) {
  5. return Promise.reject(new TypeError('Expected `concurrency` to be a number from 1 and up'));
  6. }
  7. const queue = [];
  8. let activeCount = 0;
  9. const next = () => {
  10. activeCount--;
  11. if (queue.length > 0) {
  12. queue.shift()();
  13. }
  14. };
  15. const run = (fn, resolve, ...args) => {
  16. activeCount++;
  17. const result = pTry(fn, ...args);
  18. resolve(result);
  19. result.then(next, next);
  20. };
  21. const enqueue = (fn, resolve, ...args) => {
  22. if (activeCount < concurrency) {
  23. run(fn, resolve, ...args);
  24. } else {
  25. queue.push(run.bind(null, fn, resolve, ...args));
  26. }
  27. };
  28. const generator = (fn, ...args) => new Promise(resolve => enqueue(fn, resolve, ...args));
  29. Object.defineProperties(generator, {
  30. activeCount: {
  31. get: () => activeCount
  32. },
  33. pendingCount: {
  34. get: () => queue.length
  35. }
  36. });
  37. return generator;
  38. };
  39. module.exports = pLimit;
  40. module.exports.default = pLimit;