Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CancelToken-likes? #3

Open
bergus opened this issue Jul 22, 2016 · 5 comments
Open

CancelToken-likes? #3

bergus opened this issue Jul 22, 2016 · 5 comments

Comments

@bergus
Copy link
Owner

bergus commented Jul 22, 2016

The Promise constructor takes a cancellation token argument (and lots of other API functions take one and pass it through to the promise constructor).
But what exactly should one be able to pass in there?

  • instances of CancelToken: sure
  • instances of CancelToken subclasses: probably
  • arbitrary objects as long as they have a .requested property: maybe, why not?

Actually a .requested property is not exactly enough. We need a way to register a function that synchronously cancels the promise when the cancellation is requested.
In the current proposal, RegisterPromise, CancelPromise and CancelFunction take care of this.
This also works for CancelToken subclasses, as they do have a [[RegisteredPromises]] slot as well.

And with .requested properties we need to be cautious too. Currently it is expected that it changes state exactly only once, from false to true, and that when it does that happens in the process of calling CancelFunction. This ensures that we have no pending promises whose [[CancelToken]] is .requested, and that we have no cancelled promises whose [[CancelToken]] is not .requested. (Or at least not observably to scripts, the first situation actually happens during the call to CancelFunction).
This already breaks apart for subclasses of CancelToken, who can overwrite get requested() at their own discretion. For those instances, we can actually check their [[Result]] directly like CancelToken.prototype.requested does, to ensure that we don't believe in .requested when it claims false despite the token being cancelled (see also #7 for related issues).
This is not easily possible for arbitrary objects however.

@bergus
Copy link
Owner Author

bergus commented Jul 24, 2016

The next question, after deciding what is a cancellation token, is what the constructor should do when something was passed but it's invalid.
The default would be do nothing, but I guess we could as well assume that anything (non-null, non-undefined) being passed as a second argument is supposed to be a token, and when it is invalid we could throw (ending up as rejection) before calling the executor.

@ljharb
Copy link

ljharb commented Jul 24, 2016

Doing anything besides "do nothing" would be a breaking change, since there are definitely existing scripts that return values in the executor.

@bergus
Copy link
Owner Author

bergus commented Jul 24, 2016

@ljharb But I don't know any scripts that pass something token-like as an argument besides the constructor. Of course it is a breaking change to introduce a second parameter, but I don't think it'll break anything.

@bergus
Copy link
Owner Author

bergus commented Aug 14, 2018

tc39/proposal-cancellation#22 looks like a step forward in this direction

@rbuckton
Copy link

rbuckton commented Aug 14, 2018

With tc39/proposal-cancellation#22, I would liken this to the behavior of new Map([]) vs. new Map({}). Since {} doesn't have a Symbol.iterator method, a TypeError would be thrown. However new Map(), new Map(undefined), and new Map(null) do not throw as the argument is ignored. The same would be the case for an object expected to have a Symbol.cancelSignal method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants