One key thing to recognize is that there are different reasons to
cancel an operation and as a result, different approaches to
cancellation. .NET cancellation tokens address one scenario (and do it
fairly well), where the objective is for specific operations to expose
cancellation and allow the caller to set up a way to cancel the
operation once it is in progress. This requires co-operation on both
sides but is very easy to debug and reason about.

However, this does not address all cancellation scenarios.

Another cancellation scenario is when the *consumer* of an
asynchronous task no longer needs the result of an operation. In this
case, they will only have access to the Promise unless the
cancellation token is routed to them through some other path. This
becomes especially unwieldy if you are dealing with a graph of
asynchronous operations, where you want this 'no longer needed'
property to propagate through all of the promises. This is somewhat
equivalent to how you want a garbage collector to collect a whole tree
of objects once they are no longer reachable. In JS (and in my
opinion, basically all language environments) you want this to be
explicit even if the GC is able to lazily flag the result of a promise
as no longer needed. In the 'result no longer needed' scenario there
are also cases where you do not want to cancel the operation even if
it is not needed anymore.

A third form of cancellation is already addressed by Promise
implementations - error handling. In this case, an error occurs and
the whole asynchronous process (usually) needs to be aborted and
unwound so that the error can be responded to. In this scenario
cancellation can occur at any time and in some cases it is not
possible for the application to continue correctly under these
circumstances. You could use exceptions to implement the other forms
of cancellation, but it's pretty unwieldy - and injecting exceptions
into code that doesn't expect that is a generally bad policy. .NET
used to allow injecting exceptions into other threads but has since
deprecated it because of all the nasty corner cases it introduces.

In my opinion cancellation tokens are a great model that does not
require any browser vendor/VM implementer support, but it can be
beneficial for implementations of specific operations (i.e. XHR) to
provide some sort of cancellation mechanism. Essentially, the XHR
object acts as the cancellation token and you call a method on it to
cancel. In most cases you can implement that in user space.

'Result no longer needed' requires some amount of support at the
language/base framework level, so that it is possible to flag this
state on any given Promise and it is possible for all Promise
consumers to appropriately propagate this state through graphs of
asynchronous dependencies. For example, cancelling a HTML pageload
should flag any dependent image/script loads as 'no longer needed',
but not necessarily *abort* them (aborting might kill the keepalive
connection, and allowing the request to complete might helpfully prime
the cache with those resources).

-kg

On 5 January 2016 at 19:58, Kevin Smith <zenpars...@gmail.com> wrote:
> Thanks for posting this.  Great stuff!
>
>>
>> On a page that loads 100 images four at a time, you would want 4 cleanup
>> actions registered, not 100.
>
>
> And in order to keep it to 4 you need a way to unregister the action when
> you complete the operation, which the promise API doesn't give you.  I see.
>
> Conceptually, you could of course set some "complete" flag when you finish
> the operation and then have the cleanup action early-exit if that flag is
> set, but that would be unwieldy.  And it wouldn't stop the unbounded growth
> of the promise's handler list.
>
> Interesting!
>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to