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

gra*_*hez 2 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();
Run Code Online (Sandbox Code Playgroud)

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

1)定时器回调排队

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

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

4)接下来doStuff()

4)最后doStuff()被叫

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

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

bfa*_*tto 5

你错了:

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

为什么回答以下问题:

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

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

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