使用 addeventListener 对同一事件进行多个事件侦听器

问题描述 投票:0回答:1

我在浏览器控制台中输入此代码:

document.body.addEventListener(
    "click",
    () => {
        Promise.resolve().then(() => console.log(1));
        console.log(2);
    },
    false
);

document.body.addEventListener(
    "click",
    () => {
        Promise.resolve().then(() => console.log(3));
        console.log(4);
    },
    false
);

这两个事件监听器监听点击事件并打印数字。

然后我写了一行来执行这个语句:

document.body.click();

符合我的期望,结果是:

2
4
1
3

但是,然后,我单击屏幕,事件回调被触发,结果如下:

2
1
4
3

为什么点击屏幕并手动执行

body.click()
会产生不同的结果?

javascript dom-events
1个回答
0
投票

单击与通过代码运行它看到不同结果的原因是异步操作的运行方式,尤其是 Promise。

当您手动单击屏幕时,附加到 body 元素的单击事件的事件侦听器将按照它们在代码中添加的顺序触发。 在这种情况下,第一个监听器执行,记录 2,然后记录 1,然后第二个监听器执行,分别记录 4 和 3。

2
1
4
3

运行 document.body.click(): 当您执行 document.body.click() 时,会以编程方式触发 click 事件,但由于您还使用了 Promise (Promise.resolve().then(...)),因此行为略有不同。

附加到点击事件的事件监听器仍然按照添加的顺序执行。 但是,由于 Promise,它们内部的回调(记录 1、2、3、4)可能不会立即执行,因为它们在微任务队列中排队。 这意味着,虽然在调用 document.body.click() 时立即触发 click 事件,但事件侦听器内的 Promise 会异步解析,并且稍后执行它们的回调(console.log 语句)。 因此,Promise 的异步性质导致手动点击和程序化点击之间的时间差异,从而导致记录数字的顺序不同。

我建议检查一下:微任务和承诺

© www.soinside.com 2019 - 2024. All rights reserved.