节点,如何在同步代码上超时?

时间:2018-02-10 15:24:33

标签: javascript node.js multithreading asynchronous timeout

我目前正在寻找一种使用节点在同步JavaScript代码上超时的方法。

简而言之:我有一个需要太长时间的同步代码(例如:无限循环)。我很有兴趣停止它的运行。

关于异步功能

我找到了一种使用Promise.race进行异步调用的方法,其中自定义delay承诺在Xxx毫秒后结束。 对于异步函数,代码如下:

    function timeoutIt(fun, timeMs) {
        return Promise.race([
            fun(),
            new Promise((resolve, reject) => setTimeout(reject, timeMs))
        ]);
    }

我试图派生这个片段来接收我的同步函数,但是一旦调用了函数,就永远不会执行拒绝Promise。有没有想过在同步代码上有某种超时?

  

上下文:我目前正在研究基于属性的测试框架   https://github.com/dubzzz/fast-check并希望能够工作   即使是代码进入无限循环的破坏性案例。对于   此刻,代码保持并等待测试框架超时   在它的一边

提前感谢您的帮助

1 个答案:

答案 0 :(得分:1)

在您的示例中,拒绝功能不起作用,因为javascript是单线程的。

实际上,setTimeout函数正在运行,但是在javascript线程之外运行(在浏览器队列系统中,或者在你的情况下由node.js队列系统(libuv)运行,当setTimeout完成时,处理程序(代码你)想要在超时完成时执行并且准备在事件循环中为javascript执行,但是,问题是事件循环正在处理同步代码的代码,并且永远不会到达你的处理程序。

这是一个自制的"停止infite循环的示例:



function longTimeFunction(timeAllowedInSeconds) {
    function getCurrentTime() {
        return new Date().getTime() / 1000;
    }

    const startTime = getCurrentTime();
    let stopLoop = false;
    let currentTime;

    while(1 && !stopLoop) {  //infinite loop
        //your code here, for example:
        console.log(Math.random());

        currentTime = Math.round(getCurrentTime() - startTime);

        if (currentTime >= timeAllowedInSeconds) {
            stopLoop = true;
        }
    }
};

longTimeFunction(3);




为了帮助您了解如何处理javascript中的同步和异步,我在这里放了一个很棒的视频:

Philip Roberts: What the heck is the event loop anyway? | JSConf EU 2014