节点,如何在同步代码上超时? [英] Node, How to timeout on a synchronous code?

查看:50
本文介绍了节点,如何在同步代码上超时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

简而言之:我有一个同步代码,它花费的时间太长(例如:无限循环).我会停止它的运行.

关于异步功能

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

 函数timeoutIt(fun,timeMs){返回Promise.race([乐趣(),新的Promise((resolve,reject)=> setTimeout(reject,timeMs))]);} 

我试图派生此代码段以接收我的同步函数,但是一旦调用了该函数,则拒绝承诺将永远不会执行.知道在同步代码上有某种超时吗?

上下文:我目前正在研究基于属性的测试框架 https://github.com/dubzzz/fast-check 并希望能够工作即使在代码陷入无限循环的破坏性情况下也是如此.为了此刻,代码保留并等待测试框架超时在其侧面

预先感谢您的帮助

解决方案

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

实际上,setTimeout函数可以正常运行,但是运行在javascript线程之外(在浏览器队列系统中,或者在您的情况下,由node.js队列系统(libuv)运行),当setTimeout完成时,处理程序(代码希望在超时结束时执行)插入事件队列,并准备在事件循环中针对javascript执行该事件,但是问题是事件循环正在处理您的同步代码,而从未到达您的处理程序.

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

  function longTimeFunction(timeAllowedInSeconds){函数getCurrentTime(){返回新的Date().getTime()/1000;}const startTime = getCurrentTime();让stopLoop = false;让currentTime;while(1&&!stopLoop){//无限循环//您的代码在这里,例如:console.log(Math.random());currentTime = Math.round(getCurrentTime()-startTime);如果(currentTime> = timeAllowedInSeconds){stopLoop = true;}}};longTimeFunction(3);  

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

菲利普·罗伯茨:无论如何,事件循环到底是什么呢?|JSConf EU 2014

I am currently looking for a way to timeout on a synchonous JavaScript code using node.

In a nutshell: I have a synchronous code which takes too long (for instance: an infinite loop). I would be interesting in stopping its run.

On async function

I found a way to do it on asynchronous calls using Promise.race with a custom delay promise which ends after Xxx milliseconds. For asynchronous functions the code is the following:

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

I tried to derive this snippet to receive my synchronous function, but once the function has been called the reject Promise is never executed. Any idea to have some kind of timeout on synchronous code?

Context: I am currently working on a property based testing framework https://github.com/dubzzz/fast-check and wanted to be able to work even for disruptive cases where the code goes into infinite loops. For the moment, the code holds and wait for the test framework to timeout on its side

Thanks in advance for your help

解决方案

In your example the reject function doesn't work because javascript is single threaded.

In reality, the setTimeout function is working, but runs outside of the javascript thread(in browser queue system, or in your case by the node.js queue system (libuv), when setTimeout finished, the handler (the code you want to execute when the timeout finish) is inserted in a event queue and prepared to be executed for javascript throught the event loop, but, the problem is that the event loop is processing the code of your synchronous code, and never reach your handler.

This is an "homemade" example to stops a infite loop:

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);

To help you understand the how deal with sync and async in javascript I put here one amazing video:

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

这篇关于节点,如何在同步代码上超时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆