1

我有三个功能:

let timeVar;
let savedFunctionCode;

function startTimer(code) {
savedFunctionCode = code;
timeVar = setTimeout(savedFunctionCode, 2000);
}

function resumeTimer(intervalTime = 2000) {
setTimeout(savedFunctionCode, intervalTime);
}

function stopTimer() {
clearTimeout(timeVar);
}

这样做的唯一目的基本上是一种暂停和恢复特定代码的方法。

现在在定时器被实例化(通过调用 startTimer)之后,就可以暂停或恢复代码了。

如果方法 stopTimer() 和 resumeTimer() 彼此相隔至少两秒调用,则暂停和恢复代码执行的预期行为有效。

但是,如果按此顺序调用 resumeTimer() 和 stopTimer() 的时间间隔不到两秒,则 stopTimer() 将无法成功停止/暂停 resumeTimer() 预期的执行。

我的理论:

在暂停状态下,当调用 resumeTimer 时,代码会在两秒内执行。但是,如果您快速执行 stopTimer(),则基本上没有什么可以停止的,因为 resumeTimer 的代码执行尚未开始。(不到两秒)。

所以在两秒钟内 resumeTimer() 方法执行它的代码,因为 stopTimer() 不会影响它。

问题: JavaScript 中有没有一种方法,所以当我执行 stopTimer() 时,它会取消所有待处理的代码执行。所以在这种情况下,我希望 stopTimer() 取消将在 2 秒内发生的 resumeTimer() 代码执行。

如果不清楚,请说。

例子:

<html>
<body>
 <div id="media-holder">
<span id="play-button" onclick="resumeTimer();"></span>
<span id="pause-button" onclick="stopTimer();"></span>
</div>


<script>
let timeVar = setTimeout(execute, 2000); 

function resumeTimer(intervalTime = 2000) {
    setTimeout(execute, intervalTime);
}

function stopTimer() {
    clearTimeout(timeVar);
}

function foo() {
    for(let i = 0; i < 100; i++) {
        console.log("execute");
    }
}

</script>
 <html>

如果你快速点击播放按钮和暂停按钮,它仍然会继续执行 foo() 方法,

4

1 回答 1

1

JavaScript 是单线程的。您不能在执行过程中中断函数,因为它会阻止线程调用onclick回调,直到其执行完成。

但是,您可以使用生成器设计可中断函数:

function resumeTimer() {
  task.resume();
}

function stopTimer() {
  task.pause();
}

// the `*` means this is a generator function
function* foo() {
  let i = 0;

  while (true) {
    // every `yield` statement is a point
    // where control-flow is interrupted
    yield console.log(i++);
  }
}

class Task {
  constructor(iterator, ms = 16, autoplay = true) {
    this.step = this.step.bind(this);

    this.iterator = iterator;
    this.ms = ms;

    if (autoplay) {
      this.resume();
    }
  }

  step() {
    this.result = this.iterator.next((this.result || {}).value);
  }

  pause() {
    if (this.ref) {
      clearInterval(this.ref);
      this.ref = null;
    }
  }

  resume(ms = this.ms) {
    if (ms !== this.ms) {
      this.pause();
      this.ms = ms;
    }

    if (!this.ref) {
      this.step();
      this.ref = setInterval(this.step, this.ms);
    }
  }
}

let task = new Task(foo());
<button id="play-button" onclick="resumeTimer();">Play</button>
<button id="pause-button" onclick="stopTimer();">Pause</button>

参考

于 2018-02-23T16:29:16.497 回答