iterator-zip.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. 'use strict';
  2. var call = require('../internals/function-call');
  3. var uncurryThis = require('../internals/function-uncurry-this');
  4. var createIteratorProxy = require('../internals/iterator-create-proxy');
  5. var iteratorCloseAll = require('../internals/iterator-close-all');
  6. var $TypeError = TypeError;
  7. var slice = uncurryThis([].slice);
  8. var push = uncurryThis([].push);
  9. var ITERATOR_IS_EXHAUSTED = 'Iterator is exhausted';
  10. var THROW = 'throw';
  11. // eslint-disable-next-line max-statements -- specification case
  12. var IteratorProxy = createIteratorProxy(function () {
  13. var iterCount = this.iterCount;
  14. if (!iterCount) {
  15. this.done = true;
  16. return;
  17. }
  18. var openIters = this.openIters;
  19. var iters = this.iters;
  20. var padding = this.padding;
  21. var mode = this.mode;
  22. var finishResults = this.finishResults;
  23. var results = [];
  24. var result, done;
  25. for (var i = 0; i < iterCount; i++) {
  26. var iter = iters[i];
  27. if (iter === null) {
  28. result = padding[i];
  29. } else {
  30. try {
  31. result = call(iter.next, iter.iterator);
  32. done = result.done;
  33. result = result.value;
  34. } catch (error) {
  35. openIters[i] = undefined;
  36. return iteratorCloseAll(openIters, THROW, error);
  37. }
  38. if (done) {
  39. openIters[i] = undefined;
  40. this.openItersCount--;
  41. if (mode === 'shortest') {
  42. this.done = true;
  43. return iteratorCloseAll(openIters, 'normal', undefined);
  44. }
  45. if (mode === 'strict') {
  46. if (i) {
  47. return iteratorCloseAll(openIters, THROW, new $TypeError(ITERATOR_IS_EXHAUSTED));
  48. }
  49. var open, openDone;
  50. for (var k = 1; k < iterCount; k++) {
  51. // eslint-disable-next-line max-depth -- specification case
  52. try {
  53. open = call(iters[k].next, iters[k].iterator);
  54. openDone = open.done;
  55. open = open.value;
  56. } catch (error) {
  57. openIters[k] = undefined;
  58. return iteratorCloseAll(openIters, THROW, open);
  59. }
  60. // eslint-disable-next-line max-depth -- specification case
  61. if (openDone) {
  62. openIters[k] = undefined;
  63. this.openItersCount--;
  64. } else {
  65. return iteratorCloseAll(openIters, THROW, new $TypeError(ITERATOR_IS_EXHAUSTED));
  66. }
  67. }
  68. this.done = true;
  69. return;
  70. }
  71. if (!this.openItersCount) {
  72. this.done = true;
  73. return;
  74. }
  75. iters[i] = null;
  76. result = padding[i];
  77. }
  78. }
  79. push(results, result);
  80. }
  81. return finishResults ? finishResults(results) : results;
  82. });
  83. module.exports = function (iters, mode, padding, finishResults) {
  84. var iterCount = iters.length;
  85. return new IteratorProxy({
  86. iters: iters,
  87. iterCount: iterCount,
  88. openIters: slice(iters, 0),
  89. openItersCount: iterCount,
  90. mode: mode,
  91. padding: padding,
  92. finishResults: finishResults
  93. });
  94. };