我目前正在寻找一种使用节点在同步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并希望能够工作 即使是代码进入无限循环的破坏性案例。对于 此刻,代码保持并等待测试框架超时 在它的一边
提前感谢您的帮助
答案 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