Comments (8)
I think the following example demonstrates the same issue (please correct me if I'm wrong):
const promise = new pCancelable((resolve, reject, onCancel) => {
const timeout = setTimeout(() => {
resolve(true);
}, 1000);
onCancel.shouldReject(true);
onCancel(() => {
clearTimeout(timeout);
resolve(false);
});
});
promise.shouldReject = true;
promise.cancel();
promise
.then(value => console.log(value))
.catch(console.error);
Essentially, since resolve()
is called inside the onCancel()
function, the cancellation never occurs, despite .cancel()
being called before the promise actually resolving.
I think we can fix this by changing the following code:
Lines 44 to 50 in 9fa975b
To something like this:
const onCancel = handler => {
if (!this._isPending) {
throw new Error('The `onCancel` handler was attached after the promise settled.');
}
// we need to wrap the handler to set `_isCancelled` before
// the handler function is actually invoked
const fn = (...args) => {
this._isCanceled = true;
handler(...args);
};
this._cancelHandlers.push(fn);
};
And we would change the following:
Lines 34 to 37 in 9fa975b
To something like:
const onResolve = value => {
// if the promise was already cancelled, we can stop
if (!this._isCanceled) {
this._isPending = false;
resolve(value);
}
};
If this seems like an acceptable approach and it solves the problem being described, I'd be happy to do a PR.
from p-cancelable.
Hi @szmarczak, you are defining the onCancel
in the setTimeout, so when you do cancelable.cancel();
it is not yet executed. Move the call outside the setTimeout to make it works:
const PCancelable = require('p-cancelable');
const cancelable = new PCancelable((resolve, reject, onCancel) => {
onCancel(() => console.log('Cancelled')); // It will be called
setTimeout(() => {
console.log('Timeout');
}, 1000);
});
cancelable.catch(() => {});
cancelable.cancel();
from p-cancelable.
It took me a bit to understand this too.
This is akin to adding an event listener after the event was fired, e.g.
document.click();
document.addEventListener('click', console.log);
Now in p-cancelable
terms:
p.cancel();
...
onCancel(console.log);
I think this could be achieved by treating onCancel
callbacks as .then
callbacks of a private Promise, instead of manually creating an array (_cancelHandlers
) and calling them with a loop.
from p-cancelable.
However, a failing onCancel
callback currently throws its own error:
Lines 77 to 89 in 8746e2a
And if said onCancel
callback is called after (as requested by this issue), it will no longer change the error, so the behavior would be different depending on when onCancel
is called.
from p-cancelable.
What do you mean by "cancelled already"? Can you provide an example of what's not working as expected?
The onCancel
handlers are called synchronously when use call .cancel()
:
Lines 72 to 85 in 354c400
from p-cancelable.
Sorry, here's the example:
const PCancelable = require('p-cancelable');
const cancelable = new PCancelable((resolve, reject, onCancel) => {
setTimeout(() => {
console.log('Timeout');
onCancel(() => console.log('Cancelled')); // Should this be called?
}, 1000);
});
cancelable.catch(() => {});
cancelable.cancel();
from p-cancelable.
@Spy-Seth IKR. This is not what I want. What I am trying to show, is that if onCancel callback should be called if the promise was cancelled already.
from p-cancelable.
@jonschlinkert Sounds good. PR welcome 👍
from p-cancelable.
Related Issues (19)
- Decorator
- Pass the onCancel callback as the last parameter instead of the first HOT 1
- Support wrapping an existing promise HOT 8
- React-Native: Error on module init HOT 1
- Polyfill ? HOT 1
- Passing cancellation reason to cancel handler HOT 5
- TypeScript types don't work for calling .then on a PCancelable promise HOT 4
- Not compatible with global Bluebird promises HOT 5
- Utility static function to convert executor into a PCancelable HOT 2
- Improve the message error when attaching `onCancel` after the promise settled HOT 1
- About `AbortController` HOT 2
- Convert abortable Promise-returning functions to cancelable promises
- Node Engine Lock HOT 1
- isCanceled is not set to true when shouldReject is set to false and promise is rejected in onCancel HOT 3
- Willing to add p-signal to the related section? HOT 7
- 【Discussion】Object.setPrototypeOf(PCancelable.prototype, Promise.prototype) HOT 1
- Thenable isn't cancelable anymore HOT 2
- How to use this with p-lazy? HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from p-cancelable.