Re: Re: Alternative way to achieve cancelable promise
Hi Bergi: >You're not the only one who is unsatisfied with the current proposal :-) Also >have a look at Great! I’m yet to read them but I definitely will soon to discuss more. >Promises are result values that can be passed to multiple consumers, and not >every consumer should be allowed to cancel the computation. So by default, >promises must not be cancellable. My current updated proposal allows cancellation only for promises created by `Promise.cancelable()` call. In this case, simple `return Promise.resolve(cancelablePromise)` will disallow cancellation for other consumers. But yes, this may be an opt-out rather than opt-in for APIs returning cancelable promises. >I don't see the major difference between these "chain" objects and "tokens" >from the other proposals. Can you expand on that, please? “Chain”s do not need to be passed manually. A chain will store cancelable promises and will `[@@cancel]()` them after cancellation request. Each promise will have its own chain which will again propagate cancellations. >You should never pass an async function to the new Promise constructor, have a >look here. Fortunately, the code in your actual proposal seems more reasonable >here. I agree that the constructor approach is not good and would break easily. Thus, my updated proposal now uses `Promise.cancelable(async (chain) => {})` rather than the constructor itself. >If I understood correctly, your chain keyword could be used like await? What >is the difference between them? `await` will not be automatically canceled when `chain` will: ``` cancelable function saya() { // This is theoretically cancelable but user somehow want it to be ‘atomic’. await cancelableSubWork(); chain.throwIfCanceled(); } ``` Sincerely, Kagami Sascha Rosylight ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Alternative way to achieve cancelable promise
Kagami Rosylight wrote: I want to find a way to replace cancellation token in the current [stage 1 cancelable promise proposal](https://github.com/tc39/proposal-cancelable-promises) with an alternative way which does not require passing an additional parameter. You're not the only one who is unsatisfied with the current proposal :-) Also have a look at * https://github.com/stefanpenner/random/tree/master/cancellation * https://github.com/rtm/cancelable-promise * https://github.com/bergus/promise-cancellation (mine) Here is a short representation of [my current thought](https://github.com/SaschaNaz/cancelable): ```ts // A cancelable object supports new `Symbol.cancel`. // `object[Symbol.cancel]()` will cancel any tasks related to the object. interface Cancelable { [@@cancel](): void; } interface Promise extends Cancelable {} ``` That's not going to happen. Promises are result values that can be passed to multiple consumers, and not every consumer should be allowed to cancel the computation. So by default, promises must not be cancellable. There could be such promises that can be cancelled by whomever gets a hold on them - they are known as `Task`s iirc - but that needs to be an opt-in. // Here, a new `chain` object from promise constructor callback will // help chaining cancelable tasks and provide cancellation related // helper functions. I don't see the major difference between these "chain" objects and "tokens" from the other proposals. Can you expand on that, please? function foo() { return new Promise(async (resolve, reject, chain) => { await nonCancelableSubWork1(); chain.throwIfCanceled(); // This line will throw `Cancel` object if the promise got a cancellation request await nonCancelableSubWork2(); resolve(); }); } That's not going to work. You should never pass an `async function` to the `new Promise` constructor, have a look [here](http://stackoverflow.com/a/39409757/1048572). Fortunately, the code in your actual proposal seems more reasonable here. And with some syntax sugar for readability: ```js cancelable function foo() { // `chain` is a keyword inside cancelable function blocks await nonCancelableSubWork1(); chain.throwIfCanceled(); // similar form like `new.target` await nonCancelableSubWork2(); } cancelable function bar() { chain foo(); chain baz(); } const promise = bar(); promise.cancel(); ``` If I understood correctly, your `chain` keyword could be used like `await`? What is the difference between them? But I really like the idea of `cancelable function` sugar that does the housekeeping implicitly and returns cancellable promises automatically. This very much reminds me of my own ideas https://github.com/bergus/promise-cancellation/blob/master/enhancements.md :-) kind regards, Bergi ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Alternative way to achieve cancelable promise
Thank you for your interest in my proposal. :D I also thought so and I posted [an older version of my proposal on June](https://github.com/tc39/proposal-cancelable-promises/issues/22) there. I got this answer: >This is a separate proposal, and not an issue with the proposal being >developed in this repo. So, I'll close this issue. You're welcome to continue >using it as a discussion thread for your proposal, but in general there are >better places to do that, such as es-discuss or your own GitHub repo you >created for your proposal. Thus I’m posting this here separately to gain attention and discuss. From: Marky Mark<mailto:m...@heyimmark.com> Sent: Wednesday, October 19, 2016 11:20 AM To: Kagami Rosylight<mailto:sascha...@outlook.com>; es-discuss@mozilla.org<mailto:es-discuss@mozilla.org> Subject: Re: Alternative way to achieve cancelable promise I must admit that I do like this approach, however I'm not too familiar with the proposed spec to definitively comment on this. Have you tried proposing this in the https://github.com/tc39/proposal-cancelable-promises repository? That may be a better avenue for your suggestions. On Sat, Oct 15, 2016 at 3:15 AM Kagami Rosylight <sascha...@outlook.com<mailto:sascha...@outlook.com>> wrote: I want to find a way to replace cancellation token in the current [stage 1 cancelable promise proposal](https://github.com/tc39/proposal-cancelable-promises) with an alternative way which does not require passing an additional parameter. Here is a short representation of [my current thought](https://github.com/SaschaNaz/cancelable): ```ts // A cancelable object supports new `Symbol.cancel`. // `object[Symbol.cancel]()` will cancel any tasks related to the object. interface Cancelable { [@@cancel](): void; } interface Promise extends Cancelable {} ``` ```js // Here, a new `chain` object from promise constructor callback will // help chaining cancelable tasks and provide cancellation related // helper functions. function foo() { return new Promise(async (resolve, reject, chain) => { await nonCancelableSubWork1(); chain.throwIfCanceled(); // This line will throw `Cancel` object if the promise got a cancellation request await nonCancelableSubWork2(); resolve(); }); } function bar() { return new Promise(async (resolve, reject, chain) => { // This `chain()` call will register foo() to the cancellation chain of a promise instance // and will propagate cancellation to the chained tasks. // The chain can receive any object that supports `Symbol.cancel`. await chain(foo()); await chain(baz()); }); } const promise = bar(); promise.cancel(); // This will cancel `bar` call and the cancellation will propagate to `foo` and `baz` ``` And with some syntax sugar for readability: ```js cancelable function foo() { // `chain` is a keyword inside cancelable function blocks await nonCancelableSubWork1(); chain.throwIfCanceled(); // similar form like `new.target` await nonCancelableSubWork2(); } cancelable function bar() { chain foo(); chain baz(); } const promise = bar(); promise.cancel(); cancelable function baz() { try { chain baw(); } else { // try-else block will catch cancellation, as the current existing proposal does } } ``` I think this will achieve easier and more readable flow of cancelable tasks, what do you think? ___ es-discuss mailing list es-discuss@mozilla.org<mailto:es-discuss@mozilla.org> https://mail.mozilla.org/listinfo/es-discuss -- mark Sent while riding a hoverboard... heyimmark.com<http://heyimmark.com> :) ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Alternative way to achieve cancelable promise
I must admit that I do like this approach, however I'm not too familiar with the proposed spec to definitively comment on this. Have you tried proposing this in the https://github.com/tc39/proposal-cancelable-promises repository? That may be a better avenue for your suggestions. On Sat, Oct 15, 2016 at 3:15 AM Kagami Rosylightwrote: > I want to find a way to replace cancellation token in the current [stage 1 > cancelable promise proposal]( > https://github.com/tc39/proposal-cancelable-promises) with an alternative > way which does not require passing an additional parameter. > > > > Here is a short representation of [my current thought]( > https://github.com/SaschaNaz/cancelable): > > > > ```ts > > // A cancelable object supports new `Symbol.cancel`. > > // `object[Symbol.cancel]()` will cancel any tasks related to the object. > > interface Cancelable { > > [@@cancel](): void; > > } > > > > interface Promise extends Cancelable {} > > ``` > > > > ```js > > // Here, a new `chain` object from promise constructor callback will > > // help chaining cancelable tasks and provide cancellation related > > // helper functions. > > > > function foo() { > > return new Promise(async (resolve, reject, chain) => { > > await nonCancelableSubWork1(); > > chain.throwIfCanceled(); // This line will throw `Cancel` object if > the promise got a cancellation request > > await nonCancelableSubWork2(); > > resolve(); > > }); > > } > > > > function bar() { > > return new Promise(async (resolve, reject, chain) => { > > // This `chain()` call will register foo() to the cancellation chain > of a promise instance > > // and will propagate cancellation to the chained tasks. > > // The chain can receive any object that supports `Symbol.cancel`. > > await chain(foo()); > > await chain(baz()); > > }); > > } > > > > const promise = bar(); > > promise.cancel(); // This will cancel `bar` call and the cancellation will > propagate to `foo` and `baz` > > ``` > > > > And with some syntax sugar for readability: > > > > ```js > > cancelable function foo() { > > // `chain` is a keyword inside cancelable function blocks > > await nonCancelableSubWork1(); > > chain.throwIfCanceled(); // similar form like `new.target` > > await nonCancelableSubWork2(); > > } > > > > cancelable function bar() { > > chain foo(); > > chain baz(); > > } > > > > const promise = bar(); > > promise.cancel(); > > > > cancelable function baz() { > > try { > > chain baw(); > > } > > else { > > // try-else block will catch cancellation, as the current existing > proposal does > > } > > } > > ``` > > > > I think this will achieve easier and more readable flow of cancelable > tasks, what do you think? > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -- mark Sent while riding a hoverboard... heyimmark.com :) ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss