事件处理程序,事件队列和异步行为

huangapple go评论70阅读模式
英文:

Event handlers, event queue and asynchronous behaviour

问题

以下是已经翻译好的部分:

考虑以下的React组件。我的问题不仅限于React,它是一个JavaScript问题:

function MyTest() {
  const result = () => {
    console.log("Time to play");
    setTimeout(() => {
      console.log("async");
    }, 500);
  };

  useEffect(() => {
    document.getElementById('id-1').click();
    console.log("When?");
  });

  return (
    <button id="id-1" onClick={result}>Click me</button>
  );
}

上述代码的输出是:

Time to play
When?
async

但是我对事件处理程序感到困惑。我知道的是:浏览器事件处理程序的行为与其他异步通知类似。它们在事件发生时被调度,但必须等待正在运行的其他脚本完成,然后才有机会运行。
如果上述说法正确,我会期望以下输出:

When?
Time to play
async

因为执行堆栈不是空的(console.log("When?")位于其中),以便事件处理程序运行。上述推理中有什么问题?

附言:要使上述情况更加令人困惑,请查看 https://stackoverflow.com/questions/15924014/asynchronous-or-synchronous-calling-of-event-handlers-in-javascript

英文:

Consider the following React component. My query is not limited to React. It is a Javascript question:

function MyTest(){
  const result = () =&gt;{
      console.log(&quot;Time to play&quot;);
      setTimeout (() =&gt;{
          console.log(&quot;async&quot;)
      },500);
  };
    useEffect(()=&gt;{
        document.getElementById(&#39;id-1&#39;).click();
        console.log(&quot;When?&quot;);
    })
    return (
        &lt;button id=&quot;id-1&quot; onClick={result}&gt;Click me&lt;/button&gt;
    )
}

The output of the above code is:

Time to play
When?
async

But I am confused with the event handler. What I know is: browser event handlers behave like other asynchronous notifications. They are scheduled when the event occurs but must wait for other scripts that are running to finish before they get a chance to run.
If the above is correct, I would expect the following output:

When?
Time to play
async

because the execution stack is not empty(console.log("When?") lies inside it) as for the event handler to run. What is wrong in the above syllogism?

P.S. To get the above more confusing have a look at https://stackoverflow.com/questions/15924014/asynchronous-or-synchronous-calling-of-event-handlers-in-javascript

答案1

得分: 0

查看此链接 https://w3c.github.io/uievents/#sync-async

我看到了这个:

> 事件可以同步或异步地被分发。
>
> 同步事件被视为在虚拟队列中以先入先出模型进行处理,按照事件发生的时间顺序与其他事件、DOM 更改以及用户交互的关系进行排序,每个在此虚拟队列中的事件都会被延迟,直到前一个事件完成了其传播行为或被取消。某些同步事件由特定设备或进程驱动,例如鼠标按钮事件。这些事件受到为该组事件定义的事件顺序算法的控制,用户代理将按照定义的顺序分派这些事件。

因此,我猜这个假设并不总是成立:

> 浏览器事件处理程序的行为类似于其他异步通知。

并解释了您看到的输出。

英文:

Looking at this link https://w3c.github.io/uievents/#sync-async

I see this:

> Events may be dispatched either synchronously or asynchronously.
>
> Events which are synchronous (sync events) are treated as if they are
> in a virtual queue in a first-in-first-out model, ordered by sequence
> of temporal occurrence with respect to other events, to changes in the
> DOM, and to user interaction. Each event in this virtual queue is
> delayed until the previous event has completed its propagation
> behavior, or been canceled. Some sync events are driven by a specific
> device or process, such as mouse button events. These events are
> governed by the event order algorithms defined for that set of events,
> and user agents will dispatch these events in the defined order.

So I guess this assumption isn't always the case:

> browser event handlers behave like other asynchronous notifications.

And explains why you see the output you do.

答案2

得分: 0

@Dennis Vash的评论解释了一切。

document.getElementById('id-1').click();

不会创建浏览器事件。就是这么简单。

英文:

@Dennis Vash 's comment explains everything.

document.getElementById(&#39;id-1&#39;).click();

does not create a browser event. As simple as that.

huangapple
  • 本文由 发表于 2020年1月6日 21:16:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/59612826.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定