如何让特定函数摆脱 setInterval 循环>

How to have a specific function break free from the setInterval loop>

我有以下代码和 setInterval() 方法。但是中间有一个函数,即 audio.play()。每当调用 setInterval 时,整个函数都会被再次调用,因此音频会一次又一次地播放。 运行 setInterval() 方法有什么方法但是 audio.play 部分有例外吗? 这是代码

setInterval(async () => {
    //api stuff
    const detections = await faceapi
      .detectAllFaces(video, new faceapi.TinyFaceDetectorOptions());
    const resizedDetections = faceapi.resizeResults(detections, displaySize);
    const happy  =resizedDetections[0].expressions.happy;

    //The Issue  starts from here
    if(happy>0.9)
    {
      audio.src="audios/happy_audio.wav";
      audio.play();
    }

    faceapi.draw.drawDetections(canvas, resizedDetections);
    faceapi.draw.drawFaceExpressions(canvas, resizedDetections);
  },1000)
})

如果您不希望它在播放时不播放,您可以通过检查条件中的 paused 属性 来检查音频当前是否正在播放:

setInterval(async () => {
    //api stuff
    const detections = await faceapi
      .detectAllFaces(video, new faceapi.TinyFaceDetectorOptions());
    const resizedDetections = faceapi.resizeResults(detections, displaySize);
    const happy  =resizedDetections[0].expressions.happy;

    //The Issue  starts from here
    if(!audio.paused && happy>0.9)
    {
      audio.src="audios/happy_audio.wav";
      audio.play();
    }

    faceapi.draw.drawDetections(canvas, resizedDetections);
    faceapi.draw.drawFaceExpressions(canvas, resizedDetections);
  },1000)
})

如果您只想让它触发一次,请使用标志:

let flag = false;

setInterval(async () => {
    //api stuff
    const detections = await faceapi
      .detectAllFaces(video, new faceapi.TinyFaceDetectorOptions());
    const resizedDetections = faceapi.resizeResults(detections, displaySize);
    const happy  =resizedDetections[0].expressions.happy;

    //The Issue  starts from here
    if(flag && happy>0.9)
    {
      audio.src="audios/happy_audio.wav";
      audio.play();
      flag = true;
    }

    faceapi.draw.drawDetections(canvas, resizedDetections);
    faceapi.draw.drawFaceExpressions(canvas, resizedDetections);
  },1000)
})

注意 我不太喜欢全局范围内的变量标志。在上述情况下,我建议关闭,或将异步函数绑定到包含标志的对象,但作为示例,这应该足够了:)

正如评论中已经说过的那样,更好的做法是将 setInterval 您想要 运行 的代码移出一次。

但是如果你真的想把它放在里面,那么你可以使用一个布尔变量,它只允许 运行 一次。

方法如下:

let isFirstRun = true;

setInterval(async () => {
    //api stuff
    const detections = await faceapi
      .detectAllFaces(video, new faceapi.TinyFaceDetectorOptions());
    const resizedDetections = faceapi.resizeResults(detections, displaySize);
    const happy  =resizedDetections[0].expressions.happy;

    //The Issue  starts from here
    if(isFirstRun) {
        isFirstRun = false;

        if(happy>0.9)
        {
          audio.src="audios/happy_audio.wav";
          audio.play();
        }
    }
    faceapi.draw.drawDetections(canvas, resizedDetections);
    faceapi.draw.drawFaceExpressions(canvas, resizedDetections);
  },1000)
})

我明白了。所以你想在快乐指数 > 0.9

时立即停止间隔
let intervalID = setInterval(async () => {
    //api stuff
    const detections = await faceapi
      .detectAllFaces(video, new faceapi.TinyFaceDetectorOptions());
    const resizedDetections = faceapi.resizeResults(detections, displaySize);
    const happy  =resizedDetections[0].expressions.happy;

    //The Issue  starts from here
    if(!audio.paused && happy>0.9)
    {
      audio.src="audios/happy_audio.wav";
      audio.play();
      clearInterval(intervalID); // to stop next interval
      return; // to stop current interval
    }

    faceapi.draw.drawDetections(canvas, resizedDetections);
    faceapi.draw.drawFaceExpressions(canvas, resizedDetections);
  },1000)
})