Cancel Promise pattern (no cancellable promises)

Bergi a.d.bergi at web.de
Thu Oct 27 20:25:56 UTC 2016


Jan-Ivar Bruaroey wrote:

> I'm posting this here in hopes to bring the discussion back to practical
> use cases and minimal needs.

Sorry, did we leave that somewhere? :-)

But you've got some good and important points.

> 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.

> - Token can be reused down the chain.
> - Cancellation is propagated using a regular (new) CancellationError (no
> third rail).
> - It is up to the caller whether to treat cancellations as non-exceptional.

Very important. I'd even go so far to let the caller only treat 
cancellations that he caused himself as non-exceptional.

> - Basic Promise.race pattern works even to wrap APIs that aren't
> cancellable (stop waiting)
> - Pattern allows substituting any error (though I hope we standardize
> CancelledError).
> - 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?

> I'm open to hearing what use-cases are not be covered by this.
>
> Looking forward to your feedback about
> using a regular promise as a cancellation token.

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.

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.

Kind regards,
  Bergi

-- 

Of course, my own proposal 
<https://github.com/bergus/promise-cancellation> is the holy grail. 
Feedback welcome :-)


More information about the es-discuss mailing list