javascript - 事件监听器调用函数后,代码在哪里继续执行?

标签 javascript function event-listener

编辑:对于任何困惑,我深表歉意。在我的代码中,循环在脚本中无限期地运行,直到达到特定条件。我的问题是,如果事件监听器在循环运行时调用函数,则函数完成后,将在哪里继续执行?

嗯,我想这几乎是不言自明的。事件监听器调用函数后,函数结束后代码在哪里继续执行?

最佳答案

有一个事件队列,该队列中的下一个内容都会被执行。例如,它可以是鼠标单击事件、窗口大小调整或超时。如果队列中没有任何内容,则运行 JavaScript 的容器将一直循环,直到队列中有需要处理的内容为止。

您可以在 MDN 关于 "Concurrency model and Event Loop" 的文章中阅读更多内容:

A JavaScript runtime contains a message queue, which is a list of messages to be processed. To each message is associated a function. When the stack is empty, a message is taken out of the queue and processed. The processing consists of calling the associated function (and thus creating an initial stack frame). The message processing ends when the stack becomes empty again.

将某些内容放入消息队列的常见方法是调用

setTimeout(myfunction, 0);

由于第二个参数的延迟为 0,一旦当前执行的代码完成,即调用堆栈变空,函数 myfunction 将被调用。但请注意,队列中可能已经有一些其他事件。在这种情况下,这些仍然会首先执行。

持久循环怎么办?

您在问题中添加了以下内容:

In my code, a loop is running in the script indefinitely until a certain condition is reached. My question is, if an event listener calls a function while this loop is running, after the completion of the function, where would execution continue?

如果您的循环不是通过异步调用运行(例如,重复调用 setTimeoutsetInterval),但看起来像这样:

while (!endingCondition) {
    // do nothing
}

那么就无法调用另一个(JavaScript)事件监听器。这样的事件将在消息队列中等待。仅当当前循环及其后的任何代码完成时,才会处理该事件并导致事件监听器的调用。

让我们看一下下面的例子:

var clicked = false;

document.onclick = function() {
    clicked = true;
}

while (!clicked) {};

alert('clicked!');

这里,人们可能希望 while 循环被点击中断并显示警报,但事实并非如此。单击事件将位于操作系统的消息队列中,但不会被 JavaScript 消耗,因为它总是首先完成当前正在执行的代码。如上文所述article on MDN :

whenever a function runs, it cannot be pre-empted and will run entirely before any other code runs.

任何代码都包含所有 JavaScript 代码,包括事件处理程序中的代码。

如何编写“可中断”代码

上面的例子可以像这样工作:

var clicked = false;

document.onclick = function() {
    clicked = true;
}

function detectClick() {
    if (!clicked) {
        setTimeout(detectClick, 0); // keep repeating
        return;
    }
    alert('clicked!');
    // do something more ...
};
detectClick(); // call for first time
// We get here immediately. Code will end, and events will be processed.
// One of those "events" is a time-out, to which we have set a handler: detectClick.
// At some point a click event will be there as well, triggering the other handler.

关于javascript - 事件监听器调用函数后,代码在哪里继续执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35963153/

相关文章:

javascript - 如何从 DOM 和内存中删除 DOM 元素?

javascript - 创建变量引用的函数的新实例

c++ - 为什么C++允许函数和类同名?

php - 根据连续最高的数字对分数进行排名

javascript - 带有 eventListener 的原型(prototype)内的 Array.from(..) 不起作用

javascript - 放大器值就地替换

javascript - 如何检测 $http/Restangular 中的 IHttpActionResult 状态代码?

javascript - 如何在 Angular 表达式中将 String 解析为 Int?

javascript - 无法将事件监听器添加到通过 JavaScript 创建的 div

java - @EventListener & IRequestCycle.getResponseBuilder.updateComponent 不更新组件