首页 > 解决方案 > 如何在不浪费计算的情况下暂停 javascript 方法?

问题描述

本质上,您如何暂停 javascript 执行,而不必将计算浪费在诸如 while 循环之类的东西上?

例如,假设我只想在 10 秒后执行一个功能,而不中断其他进程或浪费计算?setTimeout将不起作用,因为我希望进程在此期间实际暂停/不继续任何操作。

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

/** pause for 10 seconds */

next()

另外,如果我只想有条件地运行一个方法,每隔几秒钟或某事我可以中止操作或继续。值得注意的是,我并不是要使用setInterval,因为在这种情况下,它实际上并没有有条件地暂停实际的 javascript 执行。

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() */

标签: javascript

解决方案


一个很好的方法是在管道中创建一个块。IE

process -> pause -> next这样您就可以知道在满足特定条件之前程序的流程不会继续

你可以通过暂停内联的东西来做到这一点

...
await pause();
...

在哪里pause做超时承诺或类似的事情。这个方法我不是很了解,但是看起来比较复杂。

另一种方法是使用 while 循环停止内联执行

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

但是正如您所提到的,这会浪费大量操作,并且会干扰后台其他操作的正常运行。另一件事是您不能仅每 1 秒检查一次检查器。

我建议您改为执行以下操作:

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只有在满足超时时才会执行操作,并且在满足检查器之前不允许程序继续下一个阶段。


推荐阅读