You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript中按钮点击回调与等待的Promise之间是否可能存在竞态条件?

JavaScript中按钮点击回调与等待的Promise之间是否可能存在竞态条件?

问题场景

我有一个HTML设置页面和对应的JavaScript文件,页面展示了从后端获取的可修改配置项,底部有一个Apply按钮。具体交互逻辑如下:

  • 用户点击Apply时,$("#settings").submit(...)回调会触发,弹出一个带提示信息和OK按钮的模态框,用户可通过点击右上角X或OK关闭模态框。
  • 点击OK按钮时,$("#OK-btn").on("click"...(标记为(a))这个回调会把默认值为false的布尔变量apply_changes设为true。
  • 同时,在$("#settings").submit(...)的逻辑中,弹出模态框后会创建一个new Promise((resolve) => ...,里面给模态框绑定了modal.addEventListener("click"...(标记为(b)),用来检查apply_changes的值。

我的疑问是:用户点击模态框的OK后,设置变量的回调(a)和Promise里检查变量的回调(b)之间会不会出现竞态条件?目前测试还没遇到,但想知道底层的执行逻辑。

对应的流程示意图:

$("#settings").submit()... <displays> --->  Modal OK  ---> $("#OK-btn").on("click"... (a) set apply_changes
                  |                               ^
              <creates>                           |
                  |                               |
                  V                               |
new Promise((resolve) => eventListener("click")----
                         (b) test apply_changes

结论与解释

根据社区用户@Bergi的提示,这种情况不会出现竞态条件——关键原因在于事件的冒泡机制:当用户点击OK按钮时,事件会先从按钮元素本身向上冒泡到模态框元素。也就是说,绑定在OK按钮上的回调(a)会先执行,把apply_changes设为true,之后事件才会冒泡到模态框,触发绑定在它上面的回调(b),这时候检查到的变量值已经是更新后的了,不会出现时序混乱的问题。

优化后的实现

按照这个思路,我也重构了原本的代码,去掉了容易引发疑惑的布尔变量apply_changes,不再用额外的回调来设置它。现在直接在模态框的点击监听器里,通过$(document.activeElement).is()来判断事件到底是从哪个元素触发的,以此来决定后续的操作逻辑,代码结构更简洁清晰。

备注:内容来源于stack exchange,提问作者Dodomac

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 09:18:02