无法在异步间隔中清除计时器

Posted

技术标签:

【中文标题】无法在异步间隔中清除计时器【英文标题】:Can't clearTimer in async interval 【发布时间】:2022-01-22 14:17:45 【问题描述】:

我正在尝试使用 Java 修改一些 TensorFlow 人脸检测算法的实现。 目前,我添加了一个按钮,可以正确停止/启动相机的视频流。此外,当视频播放时,我每隔 100 毫秒检测一次上面的人脸,间隔是异步的。

当我停止然后重新启动视频流时出现问题,因为生成了多个检测。我假设它与间隔有关,因为我将检测和间隔 var 打印到控制台,并且在同一间隔中有多个检测,并且在视频获取时 clearInterval(DetTim) 之后间隔不会重置为零暂停。

我的代码如下(我省略了模型加载和 StartVideo 函数):

const video = document.getElementById('video')
const PlayButton = document.getElementById('play-button')
var DetTim = null

video.addEventListener('play', () => 
  const canvas = faceapi.createCanvasFromMedia(video)
  document.body.append(canvas)
  const displaySize =  width: video.width, height: video.height 
  faceapi.matchDimensions(canvas, displaySize)

  if (!video.paused)
    DetTim = setInterval(async () => 
      console.log(DetTim)
      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)

    , 100)
   else 
    clearInterval(DetTim)
    console.log(DetTim)
  
)


PlayButton.addEventListener("click", (e) =>
  if (video.paused) 
    video.play()
    e.target.textContent = '▌ ▌'
 else 
    video.pause()
    e.target.textContent = '▶'
  
)

另外,这里有一些与问题相关的屏幕截图。在第一个镜头中,代码可以正常工作,因为它刚刚被初始化。在第二个中,多次启动/停止点击后,在画布上绘制了多个检测(蓝色矩形)。

First Shot

Second Shot

【问题讨论】:

它是否曾经进入过else 分支?我不明白为什么会这样——因为我看不出video.paused 在那个处理函数中是怎样的......? developer.mozilla.org/en-US/docs/Web/API/htmlMediaElement/…: “当 paused 属性从 true 更改为 false 时,会触发 play 事件,这是 play 方法或 autoplay 属性的结果。” 你是对的。它没有。但是在我尝试在视频暂停时将 clearInterval 放入点击之前,并且 DetTim 保持不变。我应该如何正确实现它? 我要么在点击事件中同时处理,要么在播放和暂停事件中同时处理。将两者混合听起来不是一个好主意。 【参考方案1】:

正如a comment中提到的CBroe:

我要么在点击事件中处理两者,要么在播放和暂停事件中都处理。将两者混合,听起来不是一个好主意。

我最终在播放事件中处理了点击事件,它解决了这个问题。

【讨论】:

这并没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review

以上是关于无法在异步间隔中清除计时器的主要内容,如果未能解决你的问题,请参考以下文章

清除间隔()不工作

如何在固定时间间隔后重复执行异步任务

React hooks - 清除超时和间隔的正确方法

在if语句中添加window.location时,setInterval会冻结

关于动态修改定时器的时间间隔

重复间隔设置为每小时时 UILocalNotification 应用程序崩溃