-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
promise.timeout() doesn't cancel the original promise after the timeout #891
Comments
I hope not. |
To reproduce: bb2/cancel-bug.js var Promise = require('bluebird')
var assert = require('assert')
function assertAfter(t, str) {
return Promise.delay(t)
.cancellable()
.then(_ => console.error(str))
}
var p1 = assertAfter(1000, "Not cancelled");
var p2 = p1.timeout(500).catch(_ => _) vs bb3/cancel-bug.js var Promise = require('bluebird')
var assert = require('assert')
Promise.config({cancellation: true})
function assertAfter(t, str) {
return Promise.delay(t)
.then(_ => console.error(str))
}
var p1 = assertAfter(1000, "Not cancelled");
var p2 = p1.timeout(500).catch(_ => _)
|
Cancellation is not rejection anymore, so how would it even work? |
@petkaantonov: cancelling |
what does that have to do with timeout whose purpose is to reject with a TimeoutError? |
@petkaantonov What I meant is that .timeout() used to not only reject things, but called |
In the PR above:
Don't know if it makes sense to do it now as it may be considered a breaking change. Alternatively it may be considered a bugfix 😀 . I think its closer to BB2 behaviour (which called .cancel() on the promise). Is this in conflict with the new cancellation semantics? I can think of one potential problem - what if multiple promises are derived from the parent, would that result with unexpected cancellation? If so, that should be fixable by deriving two promises ( |
Example use case (assumes cancellation enabled) function whilist(condition, body, val = undefined) {
return Promise.resolve(condition())
.then(isTrue => !isTrue ? val : body().then(val => whilist(condition, body, val))
}
var waitButton = whilist(_ => $('.button').length === 0, () => Promise.delay(100))
waitButton.timeout(10000, "Page failed to load"); // should end `whilist` loop |
No, I'd say it's totally in line with the new cancellation semantics. One might even consider cancelling with the The only thing I'm not so sure about is whether |
You cannot cancel with anything, cancellation is not rejection anymore. |
@petkaantonov one option is to reject the derived promise but also cancel the parent one. If cancelling the parent is not a good idea due to other promises being potentially derived from it, e.g.: this should not propagate to cancel the logging because p2 and p3 prevent that (multiple derived promises that did not request/derive from a timeout): var Promise = require('bluebird');
Promise.config({
cancellation: true
});
var p1 = Promise.delay(100)
.then(_ => console.log("p1"))
var p2 = p1.delay(200).then(_ => console.log("p2"))
var p3 = p1.delay(300).then(_ => console.log("p3"))
p1.timeout(50) this should propagate to cancel the console.log and reject both p2 and p3 (only one derived promise that was "cancelled" when it timed out) var Promise = require('bluebird');
Promise.config({
cancellation: true
});
var p1 = Promise.delay(100)
.then(_ => console.log("p1")).timeout(50)
var p2 = p1.delay(200).then(_ => console.log("p2"))
var p3 = p1.delay(300).then(_ => console.log("p3")) then creating a parent/child pair within timeout then returning the child (cancelling the parent, rejecting the child) should fix that (this is not yet in the PR though) |
Well, it is to those callbacks that still observe cancellation, isn't it? I mean things like
That's fine, |
@bergus it doesn't because the original promise gets cancelled, and therefore so will the other derived promises. Which is why I suggested creating a parent and a child (or rather, a child and a grand-child), cancelling the child and rejecting the grandchild. |
Updated PR to address last point. |
Ah, I see, that's what |
Ensure timeout cancels parent (fixes #891)
With bluebird 2.x cancellable promises were being cancelled by
timeout()
however in 3.x that doen't happen even if cancellation is (globally) enabled. Is this intentional?The text was updated successfully, but these errors were encountered: