<div dir="ltr">My understanding was that it'd look like this:<div><br></div><div><div>// presumably standard</div><div>class CancelReason extends Error {}</div><div><br></div><div>// Promise.cancelable? third party library?</div><div>function cancelable(p, onCancel){</div><div>  // todo: refactor into utility function allowing: return cancelable(resultPromise, () => {xhr.abort()})</div><div>  var doCancel;</div><div>  var cancelPromise = new Promise((resolve, reject) => {</div><div>    doCancel = reason => { </div><div>      reject(new CancelReason(reason)); </div><div>      return raced;</div><div>    };</div><div>  });</div><div>  </div><div>  var raced = Promise.race([p, cancelPromise])</div><div>  .catch(reason => {</div><div>    if (reason instanceof CancelReason) {</div><div>        onCancel();</div><div>    }</div><div>    return Promise.reject(reason);</div><div>  });</div><div>  </div><div>  raced.cancel = doCancel;</div><div>  return raced;</div><div>}</div><div><br></div><div>function fetchAsync(url) {</div><div>  var resultPromise = new Promise((resolve, reject) => {</div><div>    xhr.open("GET", url, /*async:*/ true);</div><div>    xhr.onload = event => resolve(xhr.responseText);</div><div>    xhr.onerror = event => reject(xhr.statusText);</div><div>    xhr.send(null);</div><div>  });</div><div>  </div><div>  return cancelable(resultPromise, () => { xhr.abort() });</div><div>}</div></div><div><br></div><div>fetchAsync(...).then(...); // as expected<br></div><div>fetchAsync(...).cancel('reason').catch(...); // .catch gets the CancelReason, and xhr is aborted</div><div>fetchAsync(...).then(...).cancel(); // TypeError .cancel is undefined<br></div><div><br></div><div>And that cancel wouldn't automatically propagate in any way; but it is a simple callback, so can be passed around as desired.</div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Feb 27, 2015 at 9:37 PM, Ron Buckton <span dir="ltr"><<a href="mailto:rbuckton@chronicles.org" target="_blank">rbuckton@chronicles.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">




<div>
<div>
<div style="font-family:Calibri,sans-serif;font-size:11pt">AsyncJS (<a href="http://github.com/rbuckton/asyncjs" target="_blank">http://github.com/rbuckton/asyncjs</a>) 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: <a href="https://msdn.microsoft.com/en-us/library/dd997364(v=vs.110).aspx" target="_blank">https://msdn.microsoft.com/en-us/library/dd997364(v=vs.110).aspx</a><br>
<br>
Ron</div>
</div>
<div dir="ltr">
<hr>
<span style="font-family:Calibri,sans-serif;font-size:11pt;font-weight:bold">From:
</span><span style="font-family:Calibri,sans-serif;font-size:11pt"><a href="mailto:concavelenz@gmail.com" target="_blank">John Lenz</a></span><br>
<span style="font-family:Calibri,sans-serif;font-size:11pt;font-weight:bold">Sent:
</span><span style="font-family:Calibri,sans-serif;font-size:11pt">‎2/‎27/‎2015 8:01 PM</span><br>
<span style="font-family:Calibri,sans-serif;font-size:11pt;font-weight:bold">To:
</span><span style="font-family:Calibri,sans-serif;font-size:11pt"><a href="mailto:andrea.giammarchi@gmail.com" target="_blank">Andrea Giammarchi</a></span><br>
<span style="font-family:Calibri,sans-serif;font-size:11pt;font-weight:bold">Cc:
</span><span style="font-family:Calibri,sans-serif;font-size:11pt"><a href="mailto:public-script-coord@w3.org" target="_blank">public-script-coord@w3.org</a>;
<a href="mailto:es-discuss@mozilla.org" target="_blank">es-discuss</a></span><br>
<span style="font-family:Calibri,sans-serif;font-size:11pt;font-weight:bold">Subject:
</span><span style="font-family:Calibri,sans-serif;font-size:11pt">Re: Cancelable promises</span><br>
<br>
</div><div><div class="h5">
<div>
<div dir="ltr"><br>
<div class="gmail_extra"><br>
<div class="gmail_quote">On Fri, Feb 27, 2015 at 7:49 PM, John Lenz <span dir="ltr">
<<a href="mailto:concavelenz@gmail.com" target="_blank">concavelenz@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">Closure Library's promise implementation supports "cancel":
<div><br>
</div>
<div><a href="https://github.com/google/closure-library/blob/master/closure/goog/promise/promise.js#L502" target="_blank">https://github.com/google/closure-library/blob/master/closure/goog/promise/promise.js#L502</a><br>
</div>
<div><br>
</div>
<div>A promise is cancelled only if all the "child" promises are also cancelled.</div>
</div>
</blockquote>
<div><br>
</div>
<div>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.</div>
<div><br>
</div>
<div>I don't believe that "cancel" can be added after the fact and an alternative (subclass or otherwise) is needed.</div>
<div> </div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="gmail_extra"><br>
<div class="gmail_quote"><span>On Thu, Feb 26, 2015 at 11:43 PM, Andrea Giammarchi
<span dir="ltr"><<a href="mailto:andrea.giammarchi@gmail.com" target="_blank">andrea.giammarchi@gmail.com</a>></span> wrote:<br>
</span>
<div>
<div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">
<div>AFAIK bluebird did:</div>
<div><a href="https://github.com/petkaantonov/bluebird/blob/master/API.md#cancelerror-reason---promise" target="_blank">https://github.com/petkaantonov/bluebird/blob/master/API.md#cancelerror-reason---promise</a><br>
</div>
<div><br>
</div>
<div>But I agree once you've made Promises more complex than events ( xhr in this case ) nobody wins :-/</div>
<div><br>
</div>
<div>Although, specially for fetch or anything network related, there **must** be a way to bloody cancel that!</div>
<div><br>
</div>
<div>....right?</div>
<div><br>
</div>
</div>
<div>
<div>
<div class="gmail_extra"><br>
<div class="gmail_quote">On Fri, Feb 27, 2015 at 7:31 AM, Kevin Smith <span dir="ltr">
<<a href="mailto:zenparsing@gmail.com" target="_blank">zenparsing@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<p dir="ltr">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.</p>
<p dir="ltr">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.
</p>
<p dir="ltr">Has any library experimented with the cancelation token approach yet?
</p>
<div>
<div>
<div class="gmail_quote">On Feb 27, 2015 1:46 AM, "Anne van Kesteren" <<a href="mailto:annevk@annevk.nl" target="_blank">annevk@annevk.nl</a>> wrote:<br type="attribution">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
As a heads up, there's some debate around the fetch() API how exactly<br>
request termination should work and how that affects promises:<br>
<br>
  <a href="https://github.com/slightlyoff/ServiceWorker/issues/625" target="_blank">
https://github.com/slightlyoff/ServiceWorker/issues/625</a><br>
<br>
The WebRTC WG has also been discussing canceling in the context of<br>
terminating a request for permission from the user. I think they<br>
decided to postpone for now until there's a bit more progress on what<br>
cancelable promises means, but I would not expect everyone to wait<br>
forever.<br>
<br>
<br>
--<br>
<a href="https://annevankesteren.nl/" target="_blank">https://annevankesteren.nl/</a><br>
_______________________________________________<br>
es-discuss mailing list<br>
<a href="mailto:es-discuss@mozilla.org" target="_blank">es-discuss@mozilla.org</a><br>
<a href="https://mail.mozilla.org/listinfo/es-discuss" target="_blank">https://mail.mozilla.org/listinfo/es-discuss</a><br>
</blockquote>
</div>
</div>
</div>
<br>
_______________________________________________<br>
es-discuss mailing list<br>
<a href="mailto:es-discuss@mozilla.org" target="_blank">es-discuss@mozilla.org</a><br>
<a href="https://mail.mozilla.org/listinfo/es-discuss" target="_blank">https://mail.mozilla.org/listinfo/es-discuss</a><br>
<br>
</blockquote>
</div>
<br>
</div>
</div>
</div>
<br>
_______________________________________________<br>
es-discuss mailing list<br>
<a href="mailto:es-discuss@mozilla.org" target="_blank">es-discuss@mozilla.org</a><br>
<a href="https://mail.mozilla.org/listinfo/es-discuss" target="_blank">https://mail.mozilla.org/listinfo/es-discuss</a><br>
<br>
</blockquote>
</div>
</div>
</div>
<br>
</div>
</blockquote>
</div>
<br>
</div>
</div>
</div>
</div></div></div>

<br>_______________________________________________<br>
es-discuss mailing list<br>
<a href="mailto:es-discuss@mozilla.org">es-discuss@mozilla.org</a><br>
<a href="https://mail.mozilla.org/listinfo/es-discuss" target="_blank">https://mail.mozilla.org/listinfo/es-discuss</a><br>
<br></blockquote></div><br></div>