<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:"Yu Gothic";
        panose-1:2 11 4 0 0 0 0 0 0 0;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:"\@Yu Gothic";
        panose-1:2 11 4 0 0 0 0 0 0 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
.MsoChpDefault
        {mso-style-type:export-only;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style>
</head>
<body lang="EN-US" link="#0563C1" vlink="#954F72">
<div class="WordSection1">
<p class="MsoNormal">I want to find a way to replace cancellation token in the current [stage 1 cancelable promise proposal](<a href="https://github.com/tc39/proposal-cancelable-promises">https://github.com/tc39/proposal-cancelable-promises</a>) with an alternative
 way which does not require passing an additional parameter.</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Here is a short representation of [my current thought](<a href="https://github.com/SaschaNaz/cancelable">https://github.com/SaschaNaz/cancelable</a>):</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">```ts</p>
<p class="MsoNormal">// A cancelable object supports new `Symbol.cancel`.</p>
<p class="MsoNormal">// `object[Symbol.cancel]()` will cancel any tasks related to the object.</p>
<p class="MsoNormal">interface Cancelable {</p>
<p class="MsoNormal">  [@@cancel](): void;</p>
<p class="MsoNormal">}</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">interface Promise extends Cancelable {}</p>
<p class="MsoNormal">```</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">```js</p>
<p class="MsoNormal">// Here, a new `chain` object from promise constructor callback will</p>
<p class="MsoNormal">// help chaining cancelable tasks and provide cancellation related</p>
<p class="MsoNormal">// helper functions.</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">function foo() {</p>
<p class="MsoNormal">  return new Promise(async (resolve, reject, chain) => {</p>
<p class="MsoNormal">    await nonCancelableSubWork1();</p>
<p class="MsoNormal">    chain.throwIfCanceled(); // This line will throw `Cancel` object if the promise got a cancellation request</p>
<p class="MsoNormal">    await nonCancelableSubWork2();</p>
<p class="MsoNormal">    resolve();</p>
<p class="MsoNormal"> });</p>
<p class="MsoNormal">}</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">function bar() {</p>
<p class="MsoNormal">  return new Promise(async (resolve, reject, chain) => {</p>
<p class="MsoNormal">     // This `chain()` call will register foo() to the cancellation chain of a promise instance</p>
<p class="MsoNormal">     // and will propagate cancellation to the chained tasks.</p>
<p class="MsoNormal">     // The chain can receive any object that supports `Symbol.cancel`.</p>
<p class="MsoNormal">     await chain(foo());</p>
<p class="MsoNormal">     await chain(baz());</p>
<p class="MsoNormal"> });</p>
<p class="MsoNormal">}</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">const promise =  bar();</p>
<p class="MsoNormal">promise.cancel(); // This will cancel `bar` call and the cancellation will propagate to `foo` and `baz`</p>
<p class="MsoNormal">```</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">And with some syntax sugar for readability:</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">```js</p>
<p class="MsoNormal">cancelable function foo() {</p>
<p class="MsoNormal">  // `chain` is a keyword inside cancelable function blocks</p>
<p class="MsoNormal">  await nonCancelableSubWork1();</p>
<p class="MsoNormal">  chain.throwIfCanceled(); // similar form like `new.target`</p>
<p class="MsoNormal">  await nonCancelableSubWork2();</p>
<p class="MsoNormal">}</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">cancelable function bar() {</p>
<p class="MsoNormal">  chain foo();</p>
<p class="MsoNormal">  chain baz();</p>
<p class="MsoNormal">}</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">const promise = bar();</p>
<p class="MsoNormal">promise.cancel();</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">cancelable function baz() {</p>
<p class="MsoNormal">  try {</p>
<p class="MsoNormal">    chain baw();</p>
<p class="MsoNormal">  }</p>
<p class="MsoNormal">  else {</p>
<p class="MsoNormal">    // try-else block will catch cancellation, as the current existing proposal does</p>
<p class="MsoNormal">  }</p>
<p class="MsoNormal">}</p>
<p class="MsoNormal">```</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I think this will achieve easier and more readable flow of cancelable tasks, what do you think?</p>
</div>
</body>
</html>