FromIterable.js 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. 'use strict';
  2. const {Readable} = require('stream');
  3. class FromIterable extends Readable {
  4. constructor(options) {
  5. super(Object.assign({}, options, {objectMode: true}));
  6. this._iterable = null;
  7. this._next = null;
  8. if (options) {
  9. 'iterable' in options && (this._iterable = options.iterable);
  10. }
  11. !this._iterable && (this._read = this._readStop);
  12. }
  13. _read() {
  14. if (Symbol.asyncIterator && typeof this._iterable[Symbol.asyncIterator] == 'function') {
  15. this._next = this._iterable[Symbol.asyncIterator]();
  16. this._iterable = null;
  17. this._read = this._readNext;
  18. this._readNext();
  19. return;
  20. }
  21. if (Symbol.iterator && typeof this._iterable[Symbol.iterator] == 'function') {
  22. this._next = this._iterable[Symbol.iterator]();
  23. this._iterable = null;
  24. this._read = this._readNext;
  25. this._readNext();
  26. return;
  27. }
  28. if (typeof this._iterable.next == 'function') {
  29. this._next = this._iterable;
  30. this._iterable = null;
  31. this._read = this._readNext;
  32. this._readNext();
  33. return;
  34. }
  35. const result = this._iterable();
  36. this._iterable = null;
  37. if (result && typeof result.then == 'function') {
  38. result.then(value => this.push(value), error => this.emit('error', error));
  39. this._read = this._readStop;
  40. return;
  41. }
  42. if (result && typeof result.next == 'function') {
  43. this._next = result;
  44. this._read = this._readNext;
  45. this._readNext();
  46. return;
  47. }
  48. this.push(result);
  49. this._read = this._readStop;
  50. }
  51. _readNext() {
  52. for (;;) {
  53. const result = this._next.next();
  54. if (result && typeof result.then == 'function') {
  55. result.then(
  56. value => {
  57. if (value.done || value.value === null) {
  58. this.push(null);
  59. this._next = null;
  60. this._read = this._readStop;
  61. } else {
  62. this.push(value.value);
  63. }
  64. },
  65. error => this.emit('error', error)
  66. );
  67. break;
  68. }
  69. if (result.done || result.value === null) {
  70. this.push(null);
  71. this._next = null;
  72. this._read = this._readStop;
  73. break;
  74. }
  75. if (!this.push(result.value)) break;
  76. }
  77. }
  78. _readStop() {
  79. this.push(null);
  80. }
  81. static make(iterable) {
  82. return new FromIterable(typeof iterable == 'object' && iterable.iterable ? iterable : {iterable});
  83. }
  84. }
  85. FromIterable.fromIterable = FromIterable.make;
  86. FromIterable.make.Constructor = FromIterable;
  87. module.exports = FromIterable;