Home > database >  How can I make a cancel button halt this computation?
How can I make a cancel button halt this computation?

Time:01-11

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
  }
}
  • Related