-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cancellable promise? #3
Comments
I've done a https://github.com/yovanoc/eway/tree/master/src/promises/ControllablePromise |
Generally, you don't want to expose cancellation on a Note that |
These are great insights, thanks a lot @rbuckton. I'll be sure to check out Coming from C# background, I really like that in many ways In this light, I totally agree that OTOH, I would be very interested to know your opinion about possibly passing Here's the code I use for that: const prex = require('prex');
const { CancellationToken } = require('prex');
/**
* Class representing a cancellable promise.
* @extends Promise
*/
class CancellablePromise extends Promise {
static get [Symbol.species]() {
return Promise;
}
/**
* Create an instance of CancellablePromise promise.
* @param {Function} executor - accepts an object with
* the promise resolving callbacks and the cancellation token:
* { resolve, reject, cancel, token }
* @param {CancellationToken} token - a cancellation token.
*/
constructor(executor, token) {
token?.throwIfCancellationRequested();
const withCancellation = async () => {
const linkedSource = new prex.CancellationTokenSource(token?.canBeCanceled? [token]: []);
try {
const linkedToken = linkedSource.token;
const deferred = new prex.Deferred();
linkedToken.register(() => deferred.reject(new prex.CancelError()));
executor({
resolve: value => deferred.resolve(value),
reject: error => deferred.reject(error),
cancel: () => linkedSource.cancel(),
token: linkedToken,
});
await deferred.promise;
}
finally {
// this will also free all linkedToken registrations
linkedSource.close();
}
};
super((resolve, reject) => withCancellation().then(resolve, reject));
}
} This way, not only the // async delay with cancellation
function delayWithCancellation(timeoutMs, token) {
return new CancellablePromise(d => {
const id = setTimeout(d.resolve, timeoutMs);
d.token.register(() => clearTimeout(id));
// we also have an option to call d.cancel() here
}, token);
}
const tokenSource = new prex.CancellationTokenSource();
setTimeout(() => tokenSource.cancel(), 2000); // cancel after 2000ms
await delayWithCancellation(3000, tokenSource.token);
// we should not reach here Thanks for any further thoughts on this. |
@rbuckton, could you consider adding something like this
CancellablePromise
to Prex? If so, I'd be happy to collaborate on code/tests.The text was updated successfully, but these errors were encountered: