0

Essentially, how do you pause javascript execution without having to waste computation on something like a while loop?

For example, say I want to only perform a function next after 10 seconds and not interrupt other processes or waste computation? setTimeout won't work because I want the processes to actually pause / not continue any operations during that time.

const next = () => console.log("next");

/** pause for 10 seconds */

next()

Also what if I want to only run a method conditionally, where every couple seconds or something I can either abort the operation or continue. Notably I don't mean to use setInterval because in that case it's not actually conditionally pausing the actual javascript execution.

const next = () => console.log("next");

const start = new Date();
const startSeconds = now.getSeconds();
const checkEvery = 1; // seconds
const requiredDiff = 10; // seconds

const checker = () => {
    const now = new Date();
    let secondsNow = now.getSeconds();
    secondsNow < startSeconds ? secondsNow += 60 : null;
    
    const diff = secondsNow - startSeconds;
    if (diff < 10) {
        return false
    }
    return true;
}

/** something that runs checker every 1 seconds and pauses computation until checker() returns true and then runs next() */
Alita
  • 587
  • 1
  • 6
  • 16
  • 1
    Does this answer your question? [What is the JavaScript version of sleep()?](https://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep) – FZs Apr 25 '21 at 07:13
  • A modal window or a debugging breakpoint would stop the execution of all the processes. But it seems like you can not continue automatically. `sleep()` can pause the current process. – V.Volkov Apr 25 '21 at 07:27
  • Where does the ja code run? Browser, electron, nodejs, ... ? `I want the processes to actually pause / not continue any operations during that time.` what are those other operations that should not run on pause? – t.niese Apr 25 '21 at 07:43

1 Answers1

0

A good way to do this is by creating a block in the pipe. i.e.

process -> pause -> next so that you can know that the flow of the program won't continue until a certain criteria is met

You can do this by pausing things inline

...
await pause();
...

where pause is something that does a timed-out promise or something along those lines. I don't know too much about this method, but it seems relatively complicated.

Another way to do this is by stopping the execution inline with a while loop

...
// pause for 10 seconds
let result;
while (!result) { result = checker() };
...

but as you alluded to, this wastes a lot of operations and can interfere with other actions in the background from running properly. Another thing is you can't only check checker every 1 second.

I suggest you do the following instead:

const max = 20; // max number of recursive calls (i.e. timeout after 20 seconds)

// checker is a function that returns true or false and is agnostic to this implementation
// timeout is the time (in milliseconds) to wait before running the checker again
// next is the next step in your pipeline that you want to prevent from e
const pause = async (checker, timeout, next, calls = 0) => {
    if (calls > max) return; // prevents stack overflow
    const result = await checker(); // just in case your checker is async

    // if the condition was met then continue on to the next stage in your pipeline
    // if the condition was not met then run this method again to re-check in timeout
    result ? next() : setTimeout(() => pause(checker, timeout, next, calls + 1), timeout)
}

// with the functions you provided...
pause(checker, 1000, next)

pause will only execute operations when the timeout is met, and it won't allow the program to continue to the next stage until the checker is met.

Alita
  • 587
  • 1
  • 6
  • 16