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



我正在努力理解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()的所有三件事都在计时器回调触发之前完成。这比2毫秒要长得多。是的,我知道setTimeout中设置的这个时间值是不保证的。

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

你错了:

3( 计时器回调是在一个doStuff((执行和另一个之间有一段时间时运行的

原因在于以下问题的答案:

在调用异步队列中的某个内容之前,将同时执行的最小原子块是什么?

JavaScript使用一种叫做事件循环的东西。每个事件循环周期都可以称为"tick"。在每次勾选时,解释器都会检查是否有异步回调要执行(例如,超时已经过期的setTimeout回调(。

所有其他同步操作都发生在同一个刻度内。因此,在您的示例中,计时器将在下一个刻度中检查是否过期,但对doStuff的所有三个调用都在current的刻度中执行。这就是为什么传递给setTimeout的时间值不能得到保证:无法知道下一次勾选需要多长时间,所以我们通常说回调将"尽快"运行。在setInterval的情况下,一些呼叫甚至可能被丢弃;例如,当下一个tick发生在定义间隔的两倍之后时,回调只运行一次。

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

setTimeoutsetInterval或任何其他异步事件将仅在没有代码运行时处理。它们不会中断当前代码。任何正在运行的javascript代码块都会延迟所有事件处理程序的执行。

WebWorker是异步Javascript的更新解决方案。对于sencha开发人员来说,这里是教程,仍然不依赖于setTimeout

最新更新