javascript异步调用和单线程模型

时间:2015-10-17 16:31:26

标签: javascript asynchronous single-threaded

在javascript时间轴的执行阶段,会发生异步调用已注册事件处理程序的事件。根据我在异步调用中的知识,程序执行不会等待任务的完成,而是转移到下一个任务。 那么任何人都可以解释javascript如何处理在事件发生时注册到单个事件的2个事件处理函数的异步执行?

For eg:
    window.addEventListener("load",function(){console.log("onload event 1 called!");},false);
    window.addEventListener("load",function(){console.log("onload event 2 called!");},false);

javascript解释器是否只调用第一个事件处理程序并转移到第二个事件处理程序,第一个事件处理程序的执行部分是否由另一个线程执行?

我已经读过javascript遵循单线程模型,那么它是如何适应的?

2 个答案:

答案 0 :(得分:2)

  

根据我在异步调用中的知识,程序执行不等待任务完成,而是转移到下一个任务。

等待事件发生时发生异步调用。 JavaScript引擎继续执行其他任务,直到该事件触发异步回调。

  

javascript解释器是否只调用第一个事件处理程序并转到第二个事件处理程序

  

第一个事件处理程序的执行部分由另一个线程执行

没有。这些功能按顺序运行,而不是同时运行。

  

我已经读过javascript遵循单线程模型,那么它是如何适应的?

执行顺序操作。

答案 1 :(得分:0)

Javascript是单线程的,因此任何时候只能执行一段javascript代码。然而,浏览器本身是多线程的。您可以通过创建一个带有一些调用javascript alert()的闪烁CSS的页面来验证这一点。即使javascripts等待用户单击“确定”,文本仍将继续闪烁。

这也允许浏览器排队事件,即使javascript线程被占用。您可以使用以下代码验证是否属于这种情况:

function clickit()
{
    var start = Date.now();
    do
    {
    } while(Date.now() < start + 3000);
    console.log("done",start,Date.now());
}

...

<body onclick="clickit()"></body>

如果快速点击此页面,则会产生以下结果:

done 1445104179091 1445104182091
done 1445104182098 1445104185098
done 1445104185099 1445104188099
done 1445104188099 1445104191099
done 1445104191099 1445104194099

正如您所看到的,虽然在第一次单击之后,javascript线程完全忙碌,直到3秒钟,浏览器线程继续运行,并且能够排队其他点击事件,然后在clickit()后立即执行功能结束。

在您的示例中,当页面加载时,浏览器线程将两个事件放在javascript的事件队列中。然后,由于javascript处于空闲状态,它开始处理事件队列。它从顶部开始并处理第一个函数。然后当它完成时它会返回空闲状态,然后返回处理事件队列。此时第二个函数是顶部的一个,因此它运行第二个函数。