async-iterator-create-proxy.js 5.0 KB

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