如何在用户输入后结束 setTimeout

How to end setTimeout after user input

我正在 JavaScript 中开发一款游戏,其中当时钟指针比平常移动得稍微多一些时,用户需要进行按键输入(按 space 栏)。 目前,我正在使用 setTimeout 函数,在时钟指针滴答作响(旋转 10 度)后,用户有 1 秒的时间进行按键输入。 如果用户正确按下 space,当时钟指针移动超过平时(15 度)时,指示灯会闪烁绿色,否则会闪烁红色。

我 运行 遇到的问题是,一旦用户在手移动的 1 秒内输入,指示器将不会闪烁,直到 1 秒过去(即,如果用户输入0.4秒后输入一次,指示灯要等到0.6秒后才会闪烁)

我知道这是因为指标是在我的 setTimeout 函数中设置的,它只会在 1 秒后执行代码。我曾尝试测试 setTimeout 函数之外的用户输入,但那样用户不会得到 1 秒的时间来给出响应。

我想知道是否有解决这个问题的方法或更好的方法来解决这个问题?

//Get input after clock tick

setTimeout(() => {
    if (irregular_tick && space_pressed) {
        flashScreenGreen();
    }
    if (!(space_pressed) && irregular_tick) {
        flashScreenRed();
    }             
},1000);

感谢您的帮助!

我想 clearTimeout 函数在这里可以帮到你

   // Hold the reference to the timer
    const timeoutId = setTimeout(() => {
    if (irregular_tick && space_pressed) {
        flashScreenGreen();
        //You can use the clearTimeout function to end the timer
        clearTimeout(timeoutId);
    }
    if (!(space_pressed) && irregular_tick) {
        flashScreenRed();
        //clear timeout, if you need it here too
        clearTimeout(timeoutId);
    }             
},1000);

您需要在 setTimeout 回调的 外部 保留对定时器的引用,并为按键添加一个带有中断回调的侦听器,这将清除如果满足所有条件则超时。

let timer = null;
let space_pressed = false;

function reset() {
  timer = null;
  space_pressed = false;
}

function interruptHandler(e) {
  if (timer !== null) { // only look for spacebar if timer is running
    space_pressed = e.key === ' ';

    if (irregular_tick && space_pressed) {
      // clear timeOut if successful
      clearTimeout(timer);
      reset();

      flashScreenGreen();
    }
  }
}

document.body.addEventListener('keyup', interruptHandler);

timer = setTimeout(() => {
  if (!space_pressed && irregular_tick) {
    flashScreenRed();
  }

  // reset timer at end of callback ready for next run
  reset();
}, 1000);

附带说明一下,您似乎定义了两个单独的 flashScreenGreen()flashScreenRed() 函数。我猜他们有相似但不相同的逻辑。如果是这种情况,您可能需要考虑定义一个接受颜色作为参数的实用程序 flashScreen() 函数。

function flashScreen(color) {
  // logic utilizing 'color'
}

// usage
flashScreen('green');
flashScreen('#FF0000'); // red as hex