tc39 / proposal-cancelable-promises

Former home of the now-withdrawn cancelable promises proposal for JavaScript
Other
375 stars 29 forks source link

Test .requested status of CancelToken subclasses #44

Closed bergus closed 8 years ago

bergus commented 8 years ago

I think that CancelTokenIsRequested ( cancelToken ) should test the .requested property of the token. This is important when a subclass of CancelToken overwrites the getter, which is necessary to propagate cancellation immediately to dependent tokens instead of waiting some ticks for token.promise to call all its callbacks.

For any cases where we have token states depend on each other (linked tokens, waiting for all of a set to be cancelled, waiting for any of a set to be cancelled, …), we would like the state change to be reflected immediately. For that, the requested getter would be overwritten to synchronously query the states of the referenced tokens, to determine the token's own state correctly even without any asynchronous callbacks having been invoked yet.

So CancelTokenIsRequested ( cancelToken ) should become

  1. Assert: ! IsCancelToken(cancelToken) is true.
  2. If cancelToken.[[CancelTokenPromise]].[[PromiseState]] is "fulfilled", return true.
  3. Return Get(cancelToken, "requested").

and get CancelToken.prototype.requested should become

  1. Let T be the this value.
  2. If ! IsCancelToken(T) is false, throw a TypeError exception.
  3. If T.[[CancelTokenPromise]].[[PromiseState]] is "fulfilled", return true.
  4. Return false.

Step 2 in the CancelTokenIsRequested algorithm prevents falling for a lie of the overwritten getter and changing back to false even after cancel() having been called.

domenic commented 8 years ago

Super-flexible subclassing support (where you replace the base mechanism of being based on a promise controlled by the implementation) is intentionally not included. Subclassing can be used to add new capabilities based on the existing ones, but is not designed to allow you to override the fundamental mechanisms, especially in cases like this where the VM is deep inside the async function machinery and we don't want to allow it to call out to author code.

bergus commented 8 years ago

Hm, this seems to severely limit token composability (see https://github.com/zenparsing/es-cancel-token/issues/6). Has there been any work on that front?

domenic commented 8 years ago

Yes, there is agreement to add CancelToken.any (or .some).

bergus commented 8 years ago

But what about all? Will they support dynamic sets (to which you can add or even remove after having created the token)? Do we really need to put all of that in the spec instead of letting userland implementations experiment with it? I don't think testing .requested is that deep in the async machinery, and I'd expect engines to be able to optimise the cases where they deal with plain (getterless) CancelToken instances.

domenic commented 8 years ago

The committee discussed all and could not come up with any use cases.

bergus commented 8 years ago

Hm, whenever you're giving out a promise to multiple subscribers, and receive multiple cancellation tokens, you'd usually only want to cancel if no subscriber is interested any more (= all tokens are cancelled). I'm certain the community will come up with more use cases, so that's why I think tokens should be composable in userland.

bergus commented 8 years ago

Given that the need for immediate cancellation was realised in #57, should this be reopened?

domenic commented 8 years ago

No; #57 covers the plan there.