Cancel Promise pattern (no cancellable promises)

Jan-Ivar Bruaroey jib at mozilla.com
Fri Oct 28 05:32:13 UTC 2016


On 10/27/16 4:25 PM, Bergi wrote:
> But you've got some good and important points.

Thanks!

>> Things to note:
>> - Cancellation is targeted to specific operations (no "cancel chain"
>> ambition).
>
> I'd however love to be able to cancel specific chaining operations, 
> i.e. `then` callbacks.

If you try the fiddle - http://jsfiddle.net/jib1/jz33qs32/ - you'll see 
cancelling terminates the chain. If you intersperse non-cancellable 
operations, there'd be a delay if cancel is detected during those.

>> - Pattern allows chain resumption by resolving token with any desired
>> value instead.
>
> I'm not sure what you mean by "resumption". And what would that value 
> be used for?

Just basic Promise.race. If users were to resolve the cancel promise 
instead of rejecting it, it'd cancel the specific operation and inject a 
replacement success value instead of failing the remaining chain.

I'm not claiming it has utility, just avoiding inventing things. Perhaps:

     fetch("http://flo.ra/dailyflower.png", {cancel: wait(5000).then(() 
=> fetch("lily.png")})

> A crucial problem that promises don't solve is synchronous inspection. 
> If my operation was cancelled, I'd like to know immediately (before 
> starting further work) about it, instead of waiting another tick
> to be notified.

I think it'd be odd to observe cancellation and not success nor failure, 
so this seems orthogonal.

> But the fundamental problem with promises as cancellation tokens is 
> memory leaks. In your example, if the cancel button isn't clicked for 
> 10 seconds, the `token` promise will reference 3 `() => 
> clearTimeout(id)` callbacks which close over their respective `id`s. 
> Three functions and three integer ids doesn't sound like much, but in 
> real applications with long-running un-cancelled operations a token 
> could accumulate quite an amount of resources which cannot be collected.
> A clever programmer might make the callbacks become cheap no-ops, but 
> still at least the functions themselves will consume memory. For the 
> simple programmer, we need an automatic (not error-prone) 
> unsubscription mechanism once the respective cancellable operation ended.

Thanks for the links. I think I'm in the camp of not being concerned 
about this. Recall I'm not proposing new functionality, just using 
promises, so this stands to benefit from optimizations browsers ought to 
make already, without needing special attention. Once browsers optimize:

     function poll() { return isDone() || wait(1000).then(poll); }

I'll worry about this. ;)

.: Jan-Ivar :.

> Kind regards,
>  Bergi


More information about the es-discuss mailing list