浏览器中的javascript:异步任务执行模型

时间:2013-01-16 22:00:05

标签: javascript browser asynchronous

我正在努力解决javascript异步在单线程浏览器环境中的工作原理。

作为异步,我们可以同时处理定时器和xhr请求。 现在假设我有类似下面的内容

function doStuff() {
    for(var i=0; i<100000000; i++) {
        // do something to make proc busy
        if(i%1000 === 0) {
            console.log('in for loop');
        }
    }
}


setTimeout(function() {
    console.log('timed out')
}, 2);
doStuff();
doStuff();
doStuff();

定时器设置为非常小的值(2ms),所以我认为它应该如下工作:

1)计时器回调排队

2)执行doStuff()(作为一个整体?),需要一些时间(超过2毫秒)

3)运行计时器回调,因为有一个doStuff()执行和另一个

的时刻

4)下一个doStuff()被称为

4)最后doStuff()被称为

我所看到的是,在计时器回调触发之前,所有三个doStuff()事都已完成。它比那些2ms长得多。是的,我知道setTimeout中设置的时间值不能保证。

我的问题是javascript如何执行代码?在调用异步队列的某些内容之前,将立即执行的最小的原子块是什么?

3 个答案:

答案 0 :(得分:5)

你错了:

  

3)运行定时器回调,因为有一个doStuff()执行和另一个

之间的时刻

为什么回答以下问题:

  

在调用异步队列的某些内容之前,将立即执行的最小的原子块是什么?

JavaScript使用称为事件循环的内容。每个事件循环周期都可以称为“tick”。在每个tick上,解释器检查是否存在要执行的异步回调(例如,超时已经到期的setTimeout回调)。

所有其他同步操作都在同一刻度内进行。因此,在您的示例中,将在 next 标记中检查计时器是否到期,但是对doStuff的所有三次调用都在当前标记中执行。这就是为什么传递给setTimeout的时间值无法保证的原因:没有办法知道在下一个滴答之前需要多长时间,因此我们通常会说回调将“尽快”运行。在setInterval的情况下,甚至可能会删除一些呼叫;例如,当下一个滴答发生在定义的间隔的两倍之后,回调只运行一次。

答案 1 :(得分:3)

由于Javascript是单线程的,因此只有在解释器空闲时才能处理超时。当您对超时函数进行排队时,解释器仍在处理您的主脚本,并且在完成之前将无法处理超时。

只有在没有代码运行时才会处理

setTimeoutsetInterval或任何其他异步事件。它们不会中断当前代码。任何阻止运行的javascript代码都会延迟所有事件处理程序的执行。

答案 2 :(得分:0)

WebWorker是Async Javascript的更新解决方案。对于sencha开发人员here是本教程,仍然不依赖于setTimeout

相关问题