I have three functions, handleSubmit handleCancel, and solve. HandleSubmit triggers a compute-heavy process, solve. handleCancel should stop that process early.
My simplified code looks like this:
import { solve } from './solve.js';
let AllowedToRun = [false];
function handleSubmit() {
allowedToRun[0] = true;
solve(allowedToRun);
allowedToRun[0] = false;
}
function handleCancel() {
allowedToRun[0] = false;
}
// solve.js
function solve(allowedToRun) {
let n = 0;
while (n < 100000000 && allowedToRun[0]) {
n ;
console.log(n);
await sleep(0); // unblock UI by chunking compute
}
}
Essentially, once the user clicks submit, a compute heavy operation starts running. I chunk the compute with await sleep(0)
, a promisified setTimeout
, allowing for the UI to be responsive. If at any point the user clicks cancel, I mutate allowedToRun
, which will result in the while loop in solve
failing, canceling the computation early.
This is fine, and it works, but I would like to have this functionality without the use of mutating arrays and/or global variables. Is there a way this can be done without that? I would also like to import solve
, so I cannot use any module-level variables in my solution.
CodePudding user response:
I would like to have this functionality without the use of mutating arrays and/or global variables
The standard solution is to use an AbortSignal
, not an array. But either way, it's an object carrying state, and you'll have to mutate it.
function solve(abortSignal) {
let n = 0;
while (n < 100000000 && !abortSignal.aborted) {
n ;
console.log(n);
await sleep(0); // unblock UI by chunking compute
}
}
or preferably
function solve(abortSignal) {
abortSignal.throwIfAborted();
let n = 0;
while (n < 100000000) {
n ;
console.log(n);
await sleep(0, abortSignal); // unblock UI by chunking compute
}
}