如何在JavaScript中编写递归阻塞函数而不会溢出堆栈?

时间:2013-03-01 00:35:26

标签: javascript multithreading

感谢您的光临。

背景

我正在为客户端编写一个JavaScript重的应用程序,并且需要一个实用程序函数,我可以传递一个条件和一个回调函数。如果不满足条件,我需要等待几毫秒然后再次测试。如果满足条件,则执行回调。

到目前为止我有什么

我已将此方法编写为实用程序类的一部分:

 ThreadLocker: function (condition, callback) {
        //If condition is true then it resumes running code
        if (condition()) {
            callback();
        } else { //Else it waits 10ms and tries again
            setTimeout(Util.ThreadLocker(condition,callback), 10);
        }
    }

以下是它的使用方法:

   var condition = function(){return (myGlobalVariable == "foo") ? true : false;};
   var callback = function(){alert("Ready to rock!");};

    Util.Threadlocker(condition,callback);

问题

即使我将超时时间设置为10 ,我也会立即获得堆栈溢出。以下是Chrome给我的信息:

“超出最大调用堆栈大小。”

如果你看一下堆栈,看起来这个函数在一毫秒或两秒内被调用了几十次,即使setTimeOut设置为10秒也是如此。

我在这里做错了什么?

1 个答案:

答案 0 :(得分:3)

该行

setTimeout(Util.ThreadLocker(condition,callback), 10);

直接调用'ThreadLocker'函数,没有设置超时。尝试

setTimeout(function () { Util.ThreadLocker(condition,callback); }, 10);

您可能还需要知道,javaScript不是多线程的。它只是在n ms之后调度你的函数,或者只要没有执行其他任何操作就调度你的函数。对于间隔也是如此,如果您创建一个10ms的间隔:任务需要30ms,它将在第10毫秒执行,然后在第40毫秒(从第一个任务完成后)开始执行。

所以你无法真正锁定,但也没有别的东西可以竞争你的代码。

至于堆栈溢出:如果你真的有这种情况,例如。一个递归函数可能会溢出500万行的堆栈(在IE中,Number of Javascript lines executed during page load),你可以使用0的超时来推迟一个函数:

setTimeout(function () { }, 0);

这也是下划线defer工作的方式。