trouble-in-terror-town/node_modules/p-cancelable/index.js
Mikolaj 2bbacbea09 did some more work on networking and removed EOS in favor of LRM
did some more work on networking and removed EOS in favor of Light Reflective Mirror
2022-05-31 15:04:31 +02:00

103 lines
1.9 KiB
JavaScript

'use strict';
class CancelError extends Error {
constructor(reason) {
super(reason || 'Promise was canceled');
this.name = 'CancelError';
}
get isCanceled() {
return true;
}
}
class PCancelable {
static fn(userFn) {
return (...args) => {
return new PCancelable((resolve, reject, onCancel) => {
args.push(onCancel);
userFn(...args).then(resolve, reject);
});
};
}
constructor(executor) {
this._cancelHandlers = [];
this._isPending = true;
this._isCanceled = false;
this._rejectOnCancel = true;
this._promise = new Promise((resolve, reject) => {
this._reject = reject;
const onResolve = value => {
this._isPending = false;
resolve(value);
};
const onReject = error => {
this._isPending = false;
reject(error);
};
const onCancel = handler => {
this._cancelHandlers.push(handler);
};
Object.defineProperties(onCancel, {
shouldReject: {
get: () => this._rejectOnCancel,
set: bool => {
this._rejectOnCancel = bool;
}
}
});
return executor(onResolve, onReject, onCancel);
});
}
then(onFulfilled, onRejected) {
return this._promise.then(onFulfilled, onRejected);
}
catch(onRejected) {
return this._promise.catch(onRejected);
}
finally(onFinally) {
return this._promise.finally(onFinally);
}
cancel(reason) {
if (!this._isPending || this._isCanceled) {
return;
}
if (this._cancelHandlers.length > 0) {
try {
for (const handler of this._cancelHandlers) {
handler();
}
} catch (error) {
this._reject(error);
}
}
this._isCanceled = true;
if (this._rejectOnCancel) {
this._reject(new CancelError(reason));
}
}
get isCanceled() {
return this._isCanceled;
}
}
Object.setPrototypeOf(PCancelable.prototype, Promise.prototype);
module.exports = PCancelable;
module.exports.default = PCancelable;
module.exports.CancelError = CancelError;