2

假设我在 setInterval 中运行一些代码。也就是说,每隔 33 毫秒左右就会开始运行一堆代码。

在这堆代码中是一个函数,我们称之为 Overlord 函数,它根据一些状态变量的值执行其他函数。

问题是这样的:

假设 Overlord 执行 function1。假设 function1 在 33 毫秒(或任何间隔长度)之后还没有完成运行。然后 Overlord 执行 function2 而 function1 大概仍在运行。怎么了?

在javascript运行function2之前function1是否完成?javascript执行中是否内置了某种que?

谢谢!

4

3 回答 3

7

Javascript 是单线程的,因此第二个函数将被排队,但在第一个函数完成执行之前无法执行。也就是说,如果您的函数执行时间超过 33 毫秒,最好将其分成小的异步块(以防止锁定接口)。

于 2013-02-03T05:10:15.020 回答
2

这是setInterval可以很快成为一个非常糟糕的想法™ 的地方。

问题是这样的:

如果您调用setInterval(lots_O_functions, 15);将要发生的事情lots_O_functions,那么它将在 15 毫秒后被调用,但是如果需要 45 毫秒来完成所有这些工作,它不会被中断,相反,您将有两个lots_O_functions呼叫等待一旦你的第一个完成就运行......

...假设这两个也分别花费 45 毫秒,那么您现在还有 6 个lots_O_functions电话在排队等待...

那是你想要发生的事情吗?我不知道。就个人而言,我会说大多数时候不是,原因如下:

JS 在单线程上运行。事实上,在绝大多数情况下,浏览器中的几乎所有事情(点击、重新绘制页面上的元素,甚至离开页面并转到其他地方)都与同一个线程相关联。

因此,通过对繁重函数的重叠调用来阻塞线程是不好的™

相反,为什么不使用类似的东西:

var big_state_machine = { /*...*/ },
    lots_O_work = function () {
        big_state_machine.currentState.jobs.forEach(/*...*/);
        /*....... do lots o' work ......*/
        var more_work_to_do = /* figure out if you need to rerun lots_O_work */;

        if (more_work_to_do) { setTimeout(lots_O_work, 20); }
    };


lots_O_work();

现在,它会做它需要做的事情,如果之后还有更多事情要做,它会调用 setTimeout 以在该点之后至少排队20 毫秒。

setTimeout不像 asleep或 a wait,它说:“展望未来 20 毫秒,看看有多少人已经在等待做事......从那里开始,让我排在下一个可用的位置”。

这里的不同之处在于,您在第一个函数完成后 20 毫秒完成,这意味着至少需要 20 毫秒才能发生其他事情(点击、绘画、AJAX 等)。

使用setInterval,它就像,但不是在事后setTimeout在下一个可用位置排队,而是将自己设置在队列中,无论它是否准备好(或需要)。

你可以进一步分解它以保持它真正的响应,但这将是一个好的开始。

于 2013-02-03T05:24:39.697 回答
1

Javascript 是单线程的,所以你是安全的......大多数时候。function2 在 function1 完成之前运行的唯一方法是 function1 是否有任何带有回调的异步代码来完成,如 ajax 调用或另一个 setTimeout 或 setInterval。例如:

var setInterval(function(){

    //.. 
    function1();
    function2();

}, 33);

var globalVariable = 0;

var function1 = function(){
    console.log(globalVariable);

    setTimeout(function(){
        globalVariable+=2;
    }, 1000);
};
var function2 = function(){
    console.log(globalVariable);
};

该程序的输出将是。

-->0

-->0

-->2

-->2

你可能已经预料到了。

-->0

-->2

-->2

-->4

于 2013-02-03T05:22:15.847 回答