async-iterator-create-proxy.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. 'use strict';
  2. var call = require('../internals/function-call');
  3. var perform = require('../internals/perform');
  4. var anObject = require('../internals/an-object');
  5. var create = require('../internals/object-create');
  6. var createNonEnumerableProperty = require('../internals/create-non-enumerable-property');
  7. var defineBuiltIns = require('../internals/define-built-ins');
  8. var wellKnownSymbol = require('../internals/well-known-symbol');
  9. var InternalStateModule = require('../internals/internal-state');
  10. var getBuiltIn = require('../internals/get-built-in');
  11. var getMethod = require('../internals/get-method');
  12. var AsyncIteratorPrototype = require('../internals/async-iterator-prototype');
  13. var createIterResultObject = require('../internals/create-iter-result-object');
  14. var iteratorClose = require('../internals/iterator-close');
  15. var Promise = getBuiltIn('Promise');
  16. var TO_STRING_TAG = wellKnownSymbol('toStringTag');
  17. var ASYNC_ITERATOR_HELPER = 'AsyncIteratorHelper';
  18. var WRAP_FOR_VALID_ASYNC_ITERATOR = 'WrapForValidAsyncIterator';
  19. var setInternalState = InternalStateModule.set;
  20. var createAsyncIteratorProxyPrototype = function (IS_ITERATOR) {
  21. var IS_GENERATOR = !IS_ITERATOR;
  22. var getInternalState = InternalStateModule.getterFor(IS_ITERATOR ? WRAP_FOR_VALID_ASYNC_ITERATOR : ASYNC_ITERATOR_HELPER);
  23. var getStateOrEarlyExit = function (that) {
  24. var stateCompletion = perform(function () {
  25. return getInternalState(that);
  26. });
  27. var stateError = stateCompletion.error;
  28. var state = stateCompletion.value;
  29. if (stateError || (IS_GENERATOR && state.done)) {
  30. return { exit: true, value: stateError ? Promise.reject(state) : Promise.resolve(createIterResultObject(undefined, true)) };
  31. } return { exit: false, value: state };
  32. };
  33. return defineBuiltIns(create(AsyncIteratorPrototype), {
  34. next: function next() {
  35. var stateCompletion = getStateOrEarlyExit(this);
  36. var state = stateCompletion.value;
  37. if (stateCompletion.exit) return state;
  38. var handlerCompletion = perform(function () {
  39. return anObject(state.nextHandler(Promise));
  40. });
  41. var handlerError = handlerCompletion.error;
  42. var value = handlerCompletion.value;
  43. if (handlerError) state.done = true;
  44. return handlerError ? Promise.reject(value) : Promise.resolve(value);
  45. },
  46. 'return': function () {
  47. var stateCompletion = getStateOrEarlyExit(this);
  48. var state = stateCompletion.value;
  49. if (stateCompletion.exit) return state;
  50. state.done = true;
  51. var iterator = state.iterator;
  52. var returnMethod, result;
  53. var completion = perform(function () {
  54. if (state.inner) try {
  55. iteratorClose(state.inner.iterator, 'normal');
  56. } catch (error) {
  57. return iteratorClose(iterator, 'throw', error);
  58. }
  59. return getMethod(iterator, 'return');
  60. });
  61. returnMethod = result = completion.value;
  62. if (completion.error) return Promise.reject(result);
  63. if (returnMethod === undefined) return Promise.resolve(createIterResultObject(undefined, true));
  64. completion = perform(function () {
  65. return call(returnMethod, iterator);
  66. });
  67. result = completion.value;
  68. if (completion.error) return Promise.reject(result);
  69. return IS_ITERATOR ? Promise.resolve(result) : Promise.resolve(result).then(function (resolved) {
  70. anObject(resolved);
  71. return createIterResultObject(undefined, true);
  72. });
  73. }
  74. });
  75. };
  76. var WrapForValidAsyncIteratorPrototype = createAsyncIteratorProxyPrototype(true);
  77. var AsyncIteratorHelperPrototype = createAsyncIteratorProxyPrototype(false);
  78. createNonEnumerableProperty(AsyncIteratorHelperPrototype, TO_STRING_TAG, 'Async Iterator Helper');
  79. module.exports = function (nextHandler, IS_ITERATOR) {
  80. var AsyncIteratorProxy = function AsyncIterator(record, state) {
  81. if (state) {
  82. state.iterator = record.iterator;
  83. state.next = record.next;
  84. } else state = record;
  85. state.type = IS_ITERATOR ? WRAP_FOR_VALID_ASYNC_ITERATOR : ASYNC_ITERATOR_HELPER;
  86. state.nextHandler = nextHandler;
  87. state.counter = 0;
  88. state.done = false;
  89. setInternalState(this, state);
  90. };
  91. AsyncIteratorProxy.prototype = IS_ITERATOR ? WrapForValidAsyncIteratorPrototype : AsyncIteratorHelperPrototype;
  92. return AsyncIteratorProxy;
  93. };