iterator-zip.js 3.0 KB

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