clearInterval无法终止setInterval?JS中video play事件重复触发问题
问题:阻止video的play事件重复触发并终止setInterval
问题背景
点击启动按钮后,在video触发play事件时启动每100ms一次的人脸检测定时任务;点击stop按钮时终止该定时任务。但实际运行中遇到:
- play事件重复触发,导致多次创建
setInterval,调用clearInterval后仍有定时任务持续执行 interval值不断变化,无法彻底清除所有定时任务
解决方案
1. 给play事件处理加判断,避免重复创建定时器
在play事件触发时,先检查是否已有活跃的定时器,有则直接返回,不重复创建:
let interval = null; video.addEventListener('play', () => { // 已有定时器在运行,直接跳过 if (interval) return; const displaySize = { width: video.width, height: video.height } interval = setInterval(async () => { const detections = await faceapi.detectAllFaces(video, new faceapi.TinyFaceDetectorOptions()) const resizedDetections = faceapi.resizeResults(detections, displaySize) canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height) faceapi.draw.drawDetections(canvas, resizedDetections) console.log(interval,"Inside start") }, 100) })
2. 清理定时器时重置变量,可选移除play事件监听
在stop按钮点击事件中,清除定时器后务必重置interval变量;如果需要彻底防止后续触发,还可以移除play事件的监听:
// 单独提取play事件处理函数,方便后续移除监听 function handleVideoPlay() { if (interval) return; const displaySize = { width: video.width, height: video.height } interval = setInterval(async () => { const detections = await faceapi.detectAllFaces(video, new faceapi.TinyFaceDetectorOptions()) const resizedDetections = faceapi.resizeResults(detections, displaySize) canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height) faceapi.draw.drawDetections(canvas, resizedDetections) console.log(interval,"Inside start") }, 100) } video.addEventListener('play', handleVideoPlay); stop.addEventListener('click',()=>{ if (interval) { clearInterval(interval) interval = null; // 重置变量,确保下次play事件能正确判断 console.log(interval," stop is pressed " ) } video.pause(); // 主动暂停video,减少不必要的play触发 localStream.getVideoTracks()[0].stop(); video.src = ''; // 可选:移除play事件监听,彻底阻止后续触发 video.removeEventListener('play', handleVideoPlay); })
3. 排查play重复触发的其他原因
play事件重复触发可能是video播放状态反复切换导致,比如设置src后自动触发play、暂停后又意外恢复播放。除了上述处理,还可以在stop时确保video的播放状态完全终止,避免后续意外触发play事件。
内容的提问来源于stack exchange,提问作者mat
相关产品推荐
相关产品推荐

