d at domenic.me (2015-03-06T01:17:14.886Z)
My understanding was that it'd look like this:
```js
// presumably standard
class CancelReason extends Error {}
// Promise.cancelable? third party library?
function cancelable(p, onCancel){
// todo: refactor into utility function allowing: return cancelable(resultPromise, () => {xhr.abort()})
var doCancel;
var cancelPromise = new Promise((resolve, reject) => {
doCancel = reason => {
reject(new CancelReason(reason));
return raced;
};
});
var raced = Promise.race([p, cancelPromise])
.catch(reason => {
if (reason instanceof CancelReason) {
onCancel();
}
return Promise.reject(reason);
});
raced.cancel = doCancel;
return raced;
}
function fetchAsync(url) {
var resultPromise = new Promise((resolve, reject) => {
xhr.open("GET", url, /*async:*/ true);
xhr.onload = event => resolve(xhr.responseText);
xhr.onerror = event => reject(xhr.statusText);
xhr.send(null);
});
return cancelable(resultPromise, () => { xhr.abort() });
}
fetchAsync(...).then(...); // as expected
fetchAsync(...).cancel('reason').catch(...); // .catch gets the
CancelReason, and xhr is aborted
fetchAsync(...).then(...).cancel(); // TypeError .cancel is undefined
```
And that cancel wouldn't automatically propagate in any way; but it is a
simple callback, so can be passed around as desired.
My understanding was that it'd look like this: // presumably standard class CancelReason extends Error {} // Promise.cancelable? third party library? function cancelable(p, onCancel){ // todo: refactor into utility function allowing: return cancelable(resultPromise, () => {xhr.abort()}) var doCancel; var cancelPromise = new Promise((resolve, reject) => { doCancel = reason => { reject(new CancelReason(reason)); return raced; }; }); var raced = Promise.race([p, cancelPromise]) .catch(reason => { if (reason instanceof CancelReason) { onCancel(); } return Promise.reject(reason); }); raced.cancel = doCancel; return raced; } function fetchAsync(url) { var resultPromise = new Promise((resolve, reject) => { xhr.open("GET", url, /*async:*/ true); xhr.onload = event => resolve(xhr.responseText); xhr.onerror = event => reject(xhr.statusText); xhr.send(null); }); return cancelable(resultPromise, () => { xhr.abort() }); } fetchAsync(...).then(...); // as expected fetchAsync(...).cancel('reason').catch(...); // .catch gets the CancelReason, and xhr is aborted fetchAsync(...).then(...).cancel(); // TypeError .cancel is undefined And that cancel wouldn't automatically propagate in any way; but it is a simple callback, so can be passed around as desired. On Fri, Feb 27, 2015 at 9:37 PM, Ron Buckton <rbuckton at chronicles.org> wrote: > AsyncJS (http://github.com/rbuckton/asyncjs) uses a separate abstraction > for cancellation based on the .NET > CancellationTokenSource/CancellationToken types. You can find more > information about this abstraction in the MSDN documentation here: > https://msdn.microsoft.com/en-us/library/dd997364(v=vs.110).aspx > > Ron > ------------------------------ > From: John Lenz <concavelenz at gmail.com> > Sent: 2/27/2015 8:01 PM > To: Andrea Giammarchi <andrea.giammarchi at gmail.com> > Cc: public-script-coord at w3.org; es-discuss <es-discuss at mozilla.org> > Subject: Re: Cancelable promises > > > > On Fri, Feb 27, 2015 at 7:49 PM, John Lenz <concavelenz at gmail.com> wrote: > >> Closure Library's promise implementation supports "cancel": >> >> >> https://github.com/google/closure-library/blob/master/closure/goog/promise/promise.js#L502 >> >> A promise is cancelled only if all the "child" promises are also >> cancelled. >> > > I did not say that correctly, a "parent" promise can be cancelled by a > "child" it is the only child or all the children cancel. A parent can > alway cancel its children (to the children this is simply "reject"). It > does add a significant amount of complexity to the promise implementation > but it is for the most part contained there. > > I don't believe that "cancel" can be added after the fact and an > alternative (subclass or otherwise) is needed. > > >> >> On Thu, Feb 26, 2015 at 11:43 PM, Andrea Giammarchi < >> andrea.giammarchi at gmail.com> wrote: >> >>> AFAIK bluebird did: >>> >>> https://github.com/petkaantonov/bluebird/blob/master/API.md#cancelerror-reason---promise >>> >>> But I agree once you've made Promises more complex than events ( xhr >>> in this case ) nobody wins :-/ >>> >>> Although, specially for fetch or anything network related, there >>> **must** be a way to bloody cancel that! >>> >>> ....right? >>> >>> >>> On Fri, Feb 27, 2015 at 7:31 AM, Kevin Smith <zenparsing at gmail.com> >>> wrote: >>> >>>> The discussion on that github issue surrounding promise subclassing >>>> makes my head spin, especially when it comes to working out how cancelation >>>> is supposed to flow through a graph of promise dependencies. We should be >>>> wary of adding complexity to the core. >>>> >>>> The simple way to view the situation is to say that promises are simply >>>> transparent containers for asynchronous values. Control capabilities should >>>> therefore be represented by a separate abstraction. This will help keep >>>> complexity at the edges. >>>> >>>> Has any library experimented with the cancelation token approach yet? >>>> On Feb 27, 2015 1:46 AM, "Anne van Kesteren" <annevk at annevk.nl> wrote: >>>> >>>>> As a heads up, there's some debate around the fetch() API how exactly >>>>> request termination should work and how that affects promises: >>>>> >>>>> https://github.com/slightlyoff/ServiceWorker/issues/625 >>>>> >>>>> The WebRTC WG has also been discussing canceling in the context of >>>>> terminating a request for permission from the user. I think they >>>>> decided to postpone for now until there's a bit more progress on what >>>>> cancelable promises means, but I would not expect everyone to wait >>>>> forever. >>>>> >>>>> >>>>> -- >>>>> https://annevankesteren.nl/ >>>>> _______________________________________________ >>>>> es-discuss mailing list >>>>> es-discuss at mozilla.org >>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>> >>>> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> es-discuss at mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>>> >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >> > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150227/8cece319/attachment-0001.html>