You've already forked Epicnabbo-Catalogus-Updated-Daily
111 lines
2.5 KiB
JavaScript
111 lines
2.5 KiB
JavaScript
'use strict';
|
|
|
|
const { AigleProxy } = require('aigle-core');
|
|
|
|
const Aigle = require('./aigle');
|
|
const { INTERNAL, apply, call1, callProxyReciever } = require('./internal/util');
|
|
|
|
const DISPOSER = {};
|
|
|
|
class Disposer {
|
|
constructor(promise, handler) {
|
|
this._promise = promise;
|
|
this._handler = handler;
|
|
}
|
|
|
|
_dispose() {
|
|
const { _promise } = this;
|
|
switch (_promise._resolved) {
|
|
case 0:
|
|
return _promise.then(() => this._dispose());
|
|
case 1:
|
|
return call1(this._handler, this._promise._value);
|
|
}
|
|
}
|
|
}
|
|
|
|
class Using extends AigleProxy {
|
|
constructor(array, handler) {
|
|
super();
|
|
const size = array.length;
|
|
this._promise = new Aigle(INTERNAL);
|
|
this._rest = size;
|
|
this._disposed = size;
|
|
this._array = array;
|
|
this._error = undefined;
|
|
this._result = Array(size);
|
|
this._handler = handler;
|
|
let i = -1;
|
|
while (++i < size) {
|
|
const disposer = array[i];
|
|
if (disposer instanceof Disposer === false) {
|
|
callProxyReciever(disposer, this, i);
|
|
} else {
|
|
callProxyReciever(disposer._promise, this, i);
|
|
}
|
|
}
|
|
}
|
|
|
|
_spread() {
|
|
const { _handler, _result } = this;
|
|
if (typeof _handler !== 'function') {
|
|
return this._callResolve(undefined, INTERNAL);
|
|
}
|
|
callProxyReciever(apply(_handler, _result), this, INTERNAL);
|
|
}
|
|
|
|
_release() {
|
|
const { _array } = this;
|
|
let l = _array.length;
|
|
while (l--) {
|
|
const disposer = _array[l];
|
|
if (disposer instanceof Disposer === false) {
|
|
this._callResolve(disposer, DISPOSER);
|
|
} else {
|
|
callProxyReciever(disposer._dispose(), this, DISPOSER);
|
|
}
|
|
}
|
|
}
|
|
|
|
_callResolve(value, index) {
|
|
if (index === INTERNAL) {
|
|
this._result = value;
|
|
return this._release();
|
|
}
|
|
if (index === DISPOSER) {
|
|
if (--this._disposed === 0) {
|
|
if (this._error) {
|
|
this._promise._reject(this._error);
|
|
} else {
|
|
this._promise._resolve(this._result);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
this._result[index] = value;
|
|
if (--this._rest === 0) {
|
|
this._spread();
|
|
}
|
|
}
|
|
|
|
_callReject(reason) {
|
|
if (this._error) {
|
|
return this._promise._reject(reason);
|
|
}
|
|
this._error = reason;
|
|
this._release();
|
|
}
|
|
}
|
|
|
|
module.exports = { using, Disposer };
|
|
|
|
function using() {
|
|
let l = arguments.length;
|
|
const handler = arguments[--l];
|
|
const array = Array(l);
|
|
while (l--) {
|
|
array[l] = arguments[l];
|
|
}
|
|
return new Using(array, handler)._promise;
|
|
}
|