async-iterator-create-proxy.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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 ASYNC_ITERATOR_HELPER = 'AsyncIteratorHelper';
  17. var WRAP_FOR_VALID_ASYNC_ITERATOR = 'WrapForValidAsyncIterator';
  18. var setInternalState = InternalStateModule.set;
  19. var TO_STRING_TAG = wellKnownSymbol('toStringTag');
  20. var createAsyncIteratorProxyPrototype = function (IS_ITERATOR) {
  21. var IS_GENERATOR = !IS_ITERATOR;
  22. var ASYNC_ITERATOR_PROXY = IS_ITERATOR ? WRAP_FOR_VALID_ASYNC_ITERATOR : ASYNC_ITERATOR_HELPER;
  23. var getInternalState = InternalStateModule.getterFor(ASYNC_ITERATOR_PROXY);
  24. var getStateOrEarlyExit = function (that) {
  25. var stateCompletion = perform(function () {
  26. return getInternalState(that);
  27. });
  28. var stateError = stateCompletion.error;
  29. var state = stateCompletion.value;
  30. if (stateError || (IS_GENERATOR && state.done)) {
  31. return { exit: true, value: stateError ? Promise.reject(state) : Promise.resolve(createIterResultObject(undefined, true)) };
  32. } return { exit: false, value: state };
  33. };
  34. var enqueue = function (state, handler) {
  35. var task = function () {
  36. var promise = handler();
  37. if (IS_GENERATOR) {
  38. state.awaiting = promise;
  39. var clean = function () {
  40. if (state.awaiting === promise) state.awaiting = null;
  41. };
  42. promise.then(clean, clean);
  43. } return promise;
  44. };
  45. return state.awaiting ? state.awaiting = state.awaiting.then(task, task) : task();
  46. };
  47. var AsyncIteratorProxyPrototype = defineBuiltIns(create(AsyncIteratorPrototype), {
  48. next: function next() {
  49. var stateCompletion = getStateOrEarlyExit(this);
  50. var exit = stateCompletion.exit;
  51. var state = stateCompletion.value;
  52. return exit ? state : enqueue(state, function () {
  53. var handlerCompletion = perform(function () {
  54. return anObject(state.nextHandler(Promise));
  55. });
  56. var handlerError = handlerCompletion.error;
  57. var value = handlerCompletion.value;
  58. if (handlerError) state.done = true;
  59. return handlerError ? Promise.reject(value) : Promise.resolve(value);
  60. });
  61. },
  62. 'return': function () {
  63. var stateCompletion = getStateOrEarlyExit(this);
  64. var exit = stateCompletion.exit;
  65. var state = stateCompletion.value;
  66. return exit ? state : enqueue(state, function () {
  67. state.done = true;
  68. var iterator = state.iterator;
  69. var returnMethod, result;
  70. var completion = perform(function () {
  71. if (state.inner) try {
  72. iteratorClose(state.inner.iterator, '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(createIterResultObject(undefined, 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 createIterResultObject(undefined, 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.counter = 0;
  110. state.done = false;
  111. state.awaiting = null;
  112. setInternalState(this, state);
  113. };
  114. AsyncIteratorProxy.prototype = IS_ITERATOR ? WrapForValidAsyncIteratorPrototype : AsyncIteratorHelperPrototype;
  115. return AsyncIteratorProxy;
  116. };