【问题标题】:Node, How to timeout on a synchronous code?节点,如何在同步代码上超时?
【发布时间】:2018-07-21 04:44:30
【问题描述】:

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

简而言之:我的同步代码耗时太长(例如:无限循环)。我会很高兴停止它的运行。

关于异步功能

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

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

我试图派生这个 sn-p 来接收我的同步函数,但是一旦调用了该函数,reject Promise 就永远不会执行。对同步代码有某种超时的想法吗?

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

提前感谢您的帮助

【问题讨论】:

  • 不是 100% 确定,但认为您可以使用 timeout 参数运行 child process

标签: javascript node.js multithreading asynchronous timeout


【解决方案1】:

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

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

这是一个停止无限循环的“自制”示例:

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

【讨论】:

  • 确实,由于它的单线程属性,这是完全合乎逻辑的,当阻塞代码运行时,除了它自己之外没有什么可以阻止它。
  • 我只是想知道 JavaScript 或 Node 标志或选项是否有某种内置功能可以防止同步代码运行时间过长。
  • 我相信例如 Mocha 可以成功停止长脚本,但我不知道它是如何做到的:它会分叉其他进程吗?它是否通过使用 setTimeout 转换 for 循环来转换代码(实际上不可能)?它是否在自定义节点中运行?
  • 对不起 DubZzz 我不知道 Mocha 是如何工作的,我一直在看一些 lib(Runner.js、Runnable.js 和库的其他文件)github.com/mochajs/mocha/tree/master/lib希望对某些人有所帮助方式
  • 感谢您的评论,我会看看他们的实现,并在了解他们如何做到这一点后立即回到这个帖子。
猜你喜欢
  • 2018-10-10
  • 2015-03-08
  • 2014-09-18
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 2016-01-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多