你的浏览器不支持canvas

Enjoy life!

javascript - 定时器

Date: Author: JM

本文章采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。

JavaScript 是单线程语言,但它允许通过设置超时值间歇时间值来调度代码在特定的时刻执行。

一、超时调用(setTimeout

1.1 超时调用的定义

  • 超时调用:在指定的时间过后执行代码。

1.2 超时调用的实现

  • 通过使用 window 对象的 setTimeout() 方法实现。
  • setTimeout(code, time)
    • code:要执行的代码 — 可以是一个包含 JavaScript 代码的字符串(就和在 eval()函数中使用的字符串一样),也可以是一个函数。
      • 由于传递字符串可能导致性能损失,因此不建议以字符串作为第一个参数。
    • time:以毫秒表示的时间(即在执行代码前需要等待多少毫秒)。

1.3 超时调用的实质

  • 超时调用的实质:在经过setTimeout指定的时间后,所指定的代码不一定会执行。原因如下:
    • JavaScript 是一个单线程序的解释器,因此一定时间内只能执行一段代码。
    • 为了控制要执行的代码,就有一个 JavaScript 任务队列。
    • 这些任务会按照将它们添加到队列的顺序执行。
    • setTimeout()的第二个参数告诉 JavaScript 再过多长时间把当前任务添加到队列中
    • 如果队列是空的,那么添加的代码会立即执行;如果队列不是空的,那么它就要等前面的代码执行完了以后再执行

1.4 超时调用返回值和取消超时调用

  • 超时调用返回值:
    • 调用 setTimeout()之后,该方法会返回一个数值 ID,表示超时调用。
    • 这个超时调用 ID 是计划执行代码的唯一标识符,可以通过它来取消超时调用。
  • 取消超时调用:
    • 要取消尚未执行的超时调用计划,可以调用clearTimeout()方法并将相应的超时调用 ID 作为参数传递给它。
    • 只要是在指定的时间尚未过去之前调用 clearTimeout(),就可以完全取消超时调用。
//设置超时调用
var timeoutId = setTimeout(function() {
 alert("Hello world!");
}, 1000);
//注意:把它取消
clearTimeout(timeoutId); 

二、间歇调用

1.1 间歇调用的定义

  • 间歇调用:每隔指定的时间就执行一次代码。

1.2 间歇调用的实现

  • 通过使用 window 对象的 setInterval() 方法实现。
  • setInterval(code, time)
    • code:要执行的代码 — 可以是一个包含 JavaScript 代码的字符串(就和在 eval()函数中使用的字符串一样),也可以是一个函数。
      • 由于传递字符串可能导致性能损失,因此不建议以字符串作为第一个参数。
    • time:每次执行之前需要等待的毫秒数。

1.3 间歇调用的实质

  • 间歇调用的实质:它会按照指定的时间间隔重复执行代码,直至间歇调用被取消或者页面被卸载。

1.4 间歇调用返回值和取消间歇调用

  • 间歇调用返回值:
    • 调用 setInterval()之后,该方法会返回一个间歇调用 ID,表示间歇调用。
    • ID 可用于在将来某个时刻取消间歇调用。
  • 取消超时调用:
    • 取消尚未执行的间歇调用,可以使用 clearInterval() 方法并传入相应的间歇调用 ID
    • 取消间歇调用的重要性要远远高于取消超时调用,因为在不加干涉的情况下,间歇调用将会一直执行到页面卸载。

三、两种定时器的比较

例子:如果执行次数达到了 max 设定的值,则取消后续尚未执行的调用。

  • 间歇调用
var num = 0;
var max = 10;
var intervalId = null;
function incrementNumber() {
 num++;
 //如果执行次数达到了 max 设定的值,则取消后续尚未执行的调用
 if (num == max) {
     clearInterval(intervalId);
     alert("Done");
 }
}
intervalId = setInterval(incrementNumber, 500); 
  • 超时调用
var num = 0;
var max = 10;
function incrementNumber() {
 num++;
 //如果执行次数未达到 max 设定的值,则设置另一次超时调用
 if (num < max) {
 setTimeout(incrementNumber, 500);
 } else {
 alert("Done");
 }
}
setTimeout(incrementNumber, 500); 
  • 在使用超时调用时,没有必要跟踪超时调用 ID,因为每次执行代码之后,如果不再设置另一次超时调用,调用就会自行停止。
  • 一般认为,使用超时调用来模拟间歇调用的是一种最佳模式
  • 在开发环境下,很少使用真正的间歇调用。原因: 后一个间歇调用可能会在前一个间歇调用结束之前启动。
  • 而像前面示例中那样使用超时调用,则完全可以避免这一点。所以,最好不要使用间歇调用。

对于本文内容有问题或建议的小伙伴,欢迎在文章底部留言交流讨论。