定时器与事件监听
说明浏览器定时器与事件监听如何把回调安排为未来 task,以及注册、取消、重复触发与资源清理的边界。
#concept
#growing
#dev
#javascript
[!info] related notes
- 所属:异步与并发 · 浏览器 JS
- 相关:事件循环 · 事件 · addEventListener
定时器与事件监听
这个概念为什么出现
轮询库存、防抖搜索、窗口 resize、按钮点击——都依赖延后执行与监听外部事件。用错会泄漏监听、叠多个 interval、或误以为 0ms 同步。
[!abstract] 一句话理解 定时器把回调排入未来任务;事件监听把回调挂到目标上,在事件发生时进入事件循环。
与 addEventListener 原子笔记的边界
本篇讨论“定时器 + 事件监听”如何进入浏览器任务调度,以及注册、取消与清理的共同工程边界;addEventListener() 自身的参数、捕获/冒泡、once、passive 等 API 语义由 addEventListener 作为原子笔记维护。
最小示例
const id = setTimeout(() => {
console.log('poll tick')
}, 1000)
// 清理
clearTimeout(id)
function onResize() {
console.log(window.innerWidth)
}
window.addEventListener('resize', onResize)
// 组件销毁时:
// window.removeEventListener('resize', onResize)
规则
setTimeout(fn,0)≠ 同步立即setInterval可能重叠(若回调耗时)——更稳是 timeout 递归- removeEventListener 需要同一函数引用
- 被动监听/once 等选项见 addEventListener 笔记
工程实践
- 组件卸载清理定时器与监听
- 与 防抖节流 组合处理高频事件
- Node 与浏览器定时器精度/unref 行为不同
本节总结
定时器与监听是异步入口;注册时就要设计清理路径。
自测题
- 为什么 remove 时不能写匿名函数新实例?
参考答案
不是同一引用,移除失败,造成泄漏。
学习检查
- setTimeout(fn, 0) 为什么不等于同步立即执行?
- setInterval 为什么可能产生重叠或漂移问题?
- removeEventListener 为什么需要匹配相同 listener identity?
- once / passive 分别解决什么问题?
- 组件卸载时为什么必须同时考虑 timer 与 event listener 清理?