when you cancel a promise, the cancellation first bubbles to its parents as long as a parents are found that are still cancellable, this is very different from normal rejection which only propagates to children.
.timeout
does a simple normal rejection, it doesn't do cancellation, so that's why it's not possible to do it like this.
You can either cancel after a delay:
var promise = task();
Promise.delay(1000).then(function() { promise.cancel(); });
or set the timeout in the task function:
var promise = task(1000);
function task(timeout) {
return new Promise(function (resolve, reject) {
// ... a long running task ...
})
.timeout(timeout)
.cancellable()
.catch(Promise.CancellationError, function(error) {
// ... must neatly abort the task ...
console.log('Task cancelled', error);
})
.catch(Promise.TimeoutError, function(error) {
// ... must neatly abort the task ...
console.log('Task timed out', error);
});
}
You can also create a method like:
Promise.prototype.cancelAfter = function(ms) {
var self = this;
setTimeout(function() {
self.cancel();
}, ms);
return this;
};
Then
function task() {
return new Promise(function (resolve, reject) {
// ... a long running task ...
})
.cancellable()
.catch(Promise.CancellationError, function(error) {
// ... must neatly abort the task ...
console.log('Task cancelled', error);
})
}
var promise = task();
// Since it's a cancellation, it will propagate upwards so you can
// clean up in the task function
promise.cancelAfter(1000);