Slow vs immediate cancellation
by winstonchang
HTML
<h3>
Delayed cancellation
</h3>
<button onclick="startCount1()">
Start
</button>
<button onclick="cancel1()">
Cancel
</button>
<div id="output1" style="background-color: #ccc">
Output:
</div>
<br>
<h3>
Immediate cancellation
</h3>
<button onclick="startCount2()">
Start
</button>
<button onclick="cancel2()">
Cancel
</button>
<div id="output2" style="background-color: #ccc">
Output:
</div>
TypeScript
// =====================================
// Delayed cancellation
// =====================================
let cancelToken = new CancellationToken()
async function startCount1() {
const outputEl= document.getElementById("output1")
for await (const item of slowNumberStream()) {
if (isCanceled1) {
outputEl.append("Canceled!");
break;
}
outputEl.append(item);
}
}
function cancel1() {
isCanceled1 = true;
}
// =====================================
// Immediate cancellation
// =====================================
let isCanceled2 = false;
async function startCount2() {
const outputEl= document.getElementById("output2")
for await (const item of slowNumberStream()) {
if (isCanceled2) {
outputEl.append("Canceled!");
break;
}
outputEl.append(item);
}
}
function cancel2() {
isCanceled2 = true;
}
// =====================================
// Cancellation token class
// =====================================
class CancellationToken {
isCancellationRequested = false;
function onCancellationRequested(fn: ()=>{}) {
},
function cancel() {
this.isCancellationRequested = true;
}
}
// =====================================
// Number stream generator
// =====================================
async function* slowNumberStream(
n: number = 100,
delay: number = 2
): AsyncGenerator<string> {
for (let i = 0; i < n; i++) {
await new Promise((resolve) => setTimeout(resolve, delay * 1000));
yield `${i} `;
}
}