5

举个例子

var runInfinite = function(){
    while(1)
    {
       // Do stuff;
    }
};

setTimeout(runInfinite, 0);

是否有可能打破这个 runInfinite 函数形式无限运行?我的意思是可以在不使用标志或返回语句的情况下从另一个函数中杀死这个函数吗?

4

6 回答 6

5

答案是不。由于 JavaScript 是单线程的(除非您使用一些我怀疑的不太常见的实现),没有什么可以从外部破坏循环(或任何其他代码块)。

于 2013-02-14T08:32:21.630 回答
2

没有直接的方法可以“杀死”正在运行的 javascript 函数。

可能的解决方法,尽管您需要更换while(1)循环:

var i = 0; // for testing purposes

var toCall = "runInfinite()";
function runInfinite(){
    // do stuff
    console.log(i++);
    setTimeout(function(){ eval(toCall); }, 100); // or whatever timeout you want
}

setTimeout(function(){ eval(toCall); }, 0); // start the function
setTimeout(function(){ toCall = ""; }, 5000); // "kill" the function

我知道使用eval()被认为是不好的做法,但是这个想法应该很清楚。该函数setTimeout()使用变量调用自身(不是递归的,因此是 )toCall。一旦这个变量被取消设置,你就从外面杀死它。

你可以将这些变量和函数包装在一个类中,这样你就可以实现你的“kill”函数。

于 2013-02-14T08:58:05.677 回答
1

我刚刚在我的浏览器上进行了测试。

AFAIK,while(1) 块实际上会阻塞线程并且不允许其他任何东西运行。除了经验之外,我没有其他来源,但是使用 Chrome 开发人员工具包的东西ctrl+shift+i键入while(1){}会阻止其他所有内容,因为 browser-javascript 是单线程的。

但是,如果您正在使用node.js,您可能可以使用它,因为它具有多线程功能。如果有人足够熟悉node.js并愿意回答/编辑,那就去吧。我从来没有完全使用过它。

于 2013-02-14T08:33:03.963 回答
1

你想要的不是真的。但也许你做错了。如果可能,尽量不要使用while(1),如果触发了外部标志但未设置某个中断按钮,则在函数结束时再次调用该函数,否则返回

于 2013-02-14T08:33:12.083 回答
0

return 可用于停止函数的当前执行,但不适用于您的情况。

在您的情况下,您可以尝试将您的函数包装在一个try / catch 块中,您可以在您的函数将无限时找到它,基于您可以终止其当前执行。

于 2013-02-14T08:33:52.817 回答
0

我承认这并不完全相同,但是ECMA-262中有 Javascript 生成器和 Javascript 迭代器。如果您可以用生成器功能替换您的功能,那么您可以轻松实现可破坏功能。

function execWithTimeout(iter, timeout = 100) {
    const limit = Date.now() + timeout
    for (const output of iter) {
        console.log(output)
        if (Date.now() > limit) throw(new Error("Timeout reached"))
    }
}

let runInfinite = function * () {
    let i = 0
    while (1) {
        yield i++
    }
}

execWithTimeout(runInfinite())

于 2019-07-01T03:51:20.947 回答