0

在 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遵循单线程模型,那么它如何适应?

4

2 回答 2

2

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

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

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

是的

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

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

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

这强制执行顺序操作。

于 2015-10-17T16:34:12.620 回答
0

Javascript 是单线程的,因此任何时候只有一段 javascript 代码在执行。但是浏览器本身是多线程的。您可以通过使用一些闪烁的 CSS 调用 javascript alert() 创建一个页面来验证这一点。即使 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 处于空闲状态,它开始处理事件队列。它从顶部开始并处理第一个函数。然后当它完成时它会回到空闲状态,所以它会回到处理事件队列。此时第二个函数是顶部之一,所以它运行第二个函数。

于 2015-10-17T17:58:17.470 回答