123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- 'use strict';
- // https://github.com/tc39/proposal-async-explicit-resource-management
- var $ = require('../internals/export');
- var DESCRIPTORS = require('../internals/descriptors');
- var getBuiltIn = require('../internals/get-built-in');
- var aCallable = require('../internals/a-callable');
- var anInstance = require('../internals/an-instance');
- var defineBuiltIn = require('../internals/define-built-in');
- var defineBuiltIns = require('../internals/define-built-ins');
- var defineBuiltInAccessor = require('../internals/define-built-in-accessor');
- var wellKnownSymbol = require('../internals/well-known-symbol');
- var InternalStateModule = require('../internals/internal-state');
- var addDisposableResource = require('../internals/add-disposable-resource');
- var Promise = getBuiltIn('Promise');
- var SuppressedError = getBuiltIn('SuppressedError');
- var $ReferenceError = ReferenceError;
- var ASYNC_DISPOSE = wellKnownSymbol('asyncDispose');
- var TO_STRING_TAG = wellKnownSymbol('toStringTag');
- var ASYNC_DISPOSABLE_STACK = 'AsyncDisposableStack';
- var setInternalState = InternalStateModule.set;
- var getAsyncDisposableStackInternalState = InternalStateModule.getterFor(ASYNC_DISPOSABLE_STACK);
- var HINT = 'async-dispose';
- var DISPOSED = 'disposed';
- var PENDING = 'pending';
- var getPendingAsyncDisposableStackInternalState = function (stack) {
- var internalState = getAsyncDisposableStackInternalState(stack);
- if (internalState.state === DISPOSED) throw new $ReferenceError(ASYNC_DISPOSABLE_STACK + ' already disposed');
- return internalState;
- };
- var $AsyncDisposableStack = function AsyncDisposableStack() {
- setInternalState(anInstance(this, AsyncDisposableStackPrototype), {
- type: ASYNC_DISPOSABLE_STACK,
- state: PENDING,
- stack: []
- });
- if (!DESCRIPTORS) this.disposed = false;
- };
- var AsyncDisposableStackPrototype = $AsyncDisposableStack.prototype;
- defineBuiltIns(AsyncDisposableStackPrototype, {
- disposeAsync: function disposeAsync() {
- var asyncDisposableStack = this;
- return new Promise(function (resolve, reject) {
- var internalState = getAsyncDisposableStackInternalState(asyncDisposableStack);
- if (internalState.state === DISPOSED) return resolve(undefined);
- internalState.state = DISPOSED;
- if (!DESCRIPTORS) asyncDisposableStack.disposed = true;
- var stack = internalState.stack;
- var i = stack.length;
- var thrown = false;
- var suppressed;
- var handleError = function (result) {
- if (thrown) {
- suppressed = new SuppressedError(result, suppressed);
- } else {
- thrown = true;
- suppressed = result;
- }
- loop();
- };
- var loop = function () {
- if (i) {
- var disposeMethod = stack[--i];
- stack[i] = null;
- try {
- Promise.resolve(disposeMethod()).then(loop, handleError);
- } catch (error) {
- handleError(error);
- }
- } else {
- internalState.stack = null;
- thrown ? reject(suppressed) : resolve(undefined);
- }
- };
- loop();
- });
- },
- use: function use(value) {
- addDisposableResource(getPendingAsyncDisposableStackInternalState(this), value, HINT);
- return value;
- },
- adopt: function adopt(value, onDispose) {
- var internalState = getPendingAsyncDisposableStackInternalState(this);
- aCallable(onDispose);
- addDisposableResource(internalState, undefined, HINT, function () {
- return onDispose(value);
- });
- return value;
- },
- defer: function defer(onDispose) {
- var internalState = getPendingAsyncDisposableStackInternalState(this);
- aCallable(onDispose);
- addDisposableResource(internalState, undefined, HINT, onDispose);
- },
- move: function move() {
- var internalState = getPendingAsyncDisposableStackInternalState(this);
- var newAsyncDisposableStack = new $AsyncDisposableStack();
- getAsyncDisposableStackInternalState(newAsyncDisposableStack).stack = internalState.stack;
- internalState.stack = [];
- internalState.state = DISPOSED;
- if (!DESCRIPTORS) this.disposed = true;
- return newAsyncDisposableStack;
- }
- });
- if (DESCRIPTORS) defineBuiltInAccessor(AsyncDisposableStackPrototype, 'disposed', {
- configurable: true,
- get: function disposed() {
- return getAsyncDisposableStackInternalState(this).state === DISPOSED;
- }
- });
- defineBuiltIn(AsyncDisposableStackPrototype, ASYNC_DISPOSE, AsyncDisposableStackPrototype.disposeAsync, { name: 'disposeAsync' });
- defineBuiltIn(AsyncDisposableStackPrototype, TO_STRING_TAG, ASYNC_DISPOSABLE_STACK, { nonWritable: true });
- $({ global: true, constructor: true }, {
- AsyncDisposableStack: $AsyncDisposableStack
- });
|