async-iterator-create-proxy.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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 Promise = getBuiltIn('Promise');
  15. var TO_STRING_TAG = wellKnownSymbol('toStringTag');
  16. var ASYNC_ITERATOR_HELPER = 'AsyncIteratorHelper';
  17. var WRAP_FOR_VALID_ASYNC_ITERATOR = 'WrapForValidAsyncIterator';
  18. var setInternalState = InternalStateModule.set;
  19. var createAsyncIteratorProxyPrototype = function (IS_ITERATOR) {
  20. var IS_GENERATOR = !IS_ITERATOR;
  21. var getInternalState = InternalStateModule.getterFor(IS_ITERATOR ? WRAP_FOR_VALID_ASYNC_ITERATOR : ASYNC_ITERATOR_HELPER);
  22. var getStateOrEarlyExit = function (that) {
  23. var stateCompletion = perform(function () {
  24. return getInternalState(that);
  25. });
  26. var stateError = stateCompletion.error;
  27. var state = stateCompletion.value;
  28. if (stateError || (IS_GENERATOR && state.done)) {
  29. return { exit: true, value: stateError ? Promise.reject(state) : Promise.resolve(createIterResultObject(undefined, true)) };
  30. } return { exit: false, value: state };
  31. };
  32. return defineBuiltIns(create(AsyncIteratorPrototype), {
  33. next: function next() {
  34. var stateCompletion = getStateOrEarlyExit(this);
  35. var state = stateCompletion.value;
  36. if (stateCompletion.exit) return state;
  37. var handlerCompletion = perform(function () {
  38. return anObject(state.nextHandler(Promise));
  39. });
  40. var handlerError = handlerCompletion.error;
  41. var value = handlerCompletion.value;
  42. if (handlerError) state.done = true;
  43. return handlerError ? Promise.reject(value) : Promise.resolve(value);
  44. },
  45. 'return': function () {
  46. var stateCompletion = getStateOrEarlyExit(this);
  47. var state = stateCompletion.value;
  48. if (stateCompletion.exit) return state;
  49. state.done = true;
  50. var iterator = state.iterator;
  51. var inner = state.inner;
  52. var returnMethod, result;
  53. var closeOuterIterator = function () {
  54. var completion = perform(function () {
  55. return getMethod(iterator, 'return');
  56. });
  57. returnMethod = result = completion.value;
  58. if (completion.error) return Promise.reject(result);
  59. if (returnMethod === undefined) return Promise.resolve(createIterResultObject(undefined, true));
  60. completion = perform(function () {
  61. return call(returnMethod, iterator);
  62. });
  63. result = completion.value;
  64. if (completion.error) return Promise.reject(result);
  65. return IS_ITERATOR ? Promise.resolve(result) : Promise.resolve(result).then(function (resolved) {
  66. anObject(resolved);
  67. return createIterResultObject(undefined, true);
  68. });
  69. };
  70. var closeAndReject = function (error) {
  71. return closeOuterIterator().then(function () {
  72. throw error;
  73. }, function () {
  74. throw error;
  75. });
  76. };
  77. if (inner) {
  78. var innerIterator = inner.iterator;
  79. var innerReturn;
  80. var completion = perform(function () {
  81. innerReturn = getMethod(innerIterator, 'return');
  82. if (innerReturn) return call(innerReturn, innerIterator);
  83. });
  84. if (completion.error) return closeAndReject(completion.value);
  85. if (innerReturn) {
  86. return Promise.resolve(completion.value).then(function (innerResult) {
  87. try {
  88. anObject(innerResult);
  89. } catch (error) {
  90. return closeAndReject(error);
  91. }
  92. return closeOuterIterator();
  93. }, closeAndReject);
  94. }
  95. }
  96. return closeOuterIterator();
  97. }
  98. });
  99. };
  100. var WrapForValidAsyncIteratorPrototype = createAsyncIteratorProxyPrototype(true);
  101. var AsyncIteratorHelperPrototype = createAsyncIteratorProxyPrototype(false);
  102. createNonEnumerableProperty(AsyncIteratorHelperPrototype, TO_STRING_TAG, 'Async Iterator Helper');
  103. module.exports = function (nextHandler, IS_ITERATOR) {
  104. var AsyncIteratorProxy = function AsyncIterator(record, state) {
  105. if (state) {
  106. state.iterator = record.iterator;
  107. state.next = record.next;
  108. } else state = record;
  109. state.type = IS_ITERATOR ? WRAP_FOR_VALID_ASYNC_ITERATOR : ASYNC_ITERATOR_HELPER;
  110. state.nextHandler = nextHandler;
  111. state.counter = 0;
  112. state.done = false;
  113. setInternalState(this, state);
  114. };
  115. AsyncIteratorProxy.prototype = IS_ITERATOR ? WrapForValidAsyncIteratorPrototype : AsyncIteratorHelperPrototype;
  116. return AsyncIteratorProxy;
  117. };