esnext.async-iterator.flat-map.js 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. 'use strict';
  2. // https://github.com/tc39/proposal-iterator-helpers
  3. var $ = require('../internals/export');
  4. var call = require('../internals/function-call');
  5. var aCallable = require('../internals/a-callable');
  6. var anObject = require('../internals/an-object');
  7. var getIteratorDirect = require('../internals/get-iterator-direct');
  8. var createAsyncIteratorProxy = require('../internals/async-iterator-create-proxy');
  9. var getAsyncIterator = require('../internals/get-async-iterator');
  10. var closeAsyncIteration = require('../internals/async-iterator-close');
  11. var AsyncIteratorProxy = createAsyncIteratorProxy(function (Promise) {
  12. var state = this;
  13. var iterator = state.iterator;
  14. var mapper = state.mapper;
  15. var innerIterator;
  16. return new Promise(function (resolve, reject) {
  17. var doneAndReject = function (error) {
  18. state.done = true;
  19. reject(error);
  20. };
  21. var ifAbruptCloseAsyncIterator = function (error) {
  22. closeAsyncIteration(iterator, doneAndReject, error, doneAndReject);
  23. };
  24. var outerLoop = function () {
  25. try {
  26. Promise.resolve(anObject(call(state.next, iterator))).then(function (step) {
  27. try {
  28. if (anObject(step).done) {
  29. state.done = true;
  30. resolve({ value: undefined, done: true });
  31. } else {
  32. var value = step.value;
  33. try {
  34. Promise.resolve(mapper(value)).then(function (mapped) {
  35. try {
  36. state.innerIterator = innerIterator = getAsyncIterator(mapped);
  37. state.innerNext = aCallable(innerIterator.next);
  38. innerLoop();
  39. } catch (error4) { ifAbruptCloseAsyncIterator(error4); }
  40. }, ifAbruptCloseAsyncIterator);
  41. } catch (error3) { ifAbruptCloseAsyncIterator(error3); }
  42. }
  43. } catch (error2) { doneAndReject(error2); }
  44. }, doneAndReject);
  45. } catch (error) { doneAndReject(error); }
  46. };
  47. var innerLoop = function () {
  48. if (innerIterator = state.innerIterator) {
  49. try {
  50. Promise.resolve(anObject(call(state.innerNext, innerIterator))).then(function (result) {
  51. try {
  52. if (anObject(result).done) {
  53. state.innerIterator = state.innerNext = null;
  54. outerLoop();
  55. } else resolve({ value: result.value, done: false });
  56. } catch (error1) { ifAbruptCloseAsyncIterator(error1); }
  57. }, ifAbruptCloseAsyncIterator);
  58. } catch (error) { ifAbruptCloseAsyncIterator(error); }
  59. } else outerLoop();
  60. };
  61. innerLoop();
  62. });
  63. });
  64. $({ target: 'AsyncIterator', proto: true, real: true, forced: true }, {
  65. flatMap: function flatMap(mapper) {
  66. return new AsyncIteratorProxy(getIteratorDirect(this), {
  67. mapper: aCallable(mapper),
  68. innerIterator: null,
  69. innerNext: null
  70. });
  71. }
  72. });