iterate-stream.js 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. "use strict";
  2. module.exports = async function* iterateStream(stream) {
  3. const contents = [];
  4. stream.on('data', data => contents.push(data));
  5. let resolveStreamEndedPromise;
  6. const streamEndedPromise = new Promise(resolve => resolveStreamEndedPromise = resolve);
  7. let ended = false;
  8. stream.on('end', () => {
  9. ended = true;
  10. resolveStreamEndedPromise();
  11. });
  12. let error = false;
  13. stream.on('error', err => {
  14. error = err;
  15. resolveStreamEndedPromise();
  16. });
  17. while (!ended || contents.length > 0) {
  18. if (contents.length === 0) {
  19. stream.resume();
  20. // eslint-disable-next-line no-await-in-loop
  21. await Promise.race([once(stream, 'data'), streamEndedPromise]);
  22. } else {
  23. stream.pause();
  24. const data = contents.shift();
  25. yield data;
  26. }
  27. if (error) throw error;
  28. }
  29. resolveStreamEndedPromise();
  30. };
  31. function once(eventEmitter, type) {
  32. // TODO: Use require('events').once when node v10 is dropped
  33. return new Promise(resolve => {
  34. let fired = false;
  35. const handler = () => {
  36. if (!fired) {
  37. fired = true;
  38. eventEmitter.removeListener(type, handler);
  39. resolve();
  40. }
  41. };
  42. eventEmitter.addListener(type, handler);
  43. });
  44. }
  45. //# sourceMappingURL=iterate-stream.js.map