Skip to content

Files

Latest commit

 

History

History
80 lines (67 loc) · 4.72 KB

7.1.3.md

File metadata and controls

80 lines (67 loc) · 4.72 KB

7.1.3 实现定时器功能 -setInterval/setTimeout方法

  经常会有「每隔一定的时间,或者是经过一定的时间之后执行某个处理」这样的情况,这时,可以使用setInterval/setTimeout方法。首先,我们来看下具体的例子吧。

【359页】

●清单7-02 interval.html(上)/interval.js(下) image

<!--点击按钮时停止定时器处理-->
// 将当前时间显示到<div id='result'>元素中(每5000毫秒更新一次)
// 点击按钮时停止定时器处理
JavaScript完全学习教程
停止定时器
JavaScript完全学习教程
停止定时器

●每5000毫秒更新当前时间

  setInterval/setTimeout方法的写法如下。

●语法 setInterval/setTimeout方法 image

func:执行的处理
dur:时间间隔(单位是毫秒)

  两者很相似,但也有下面的差异。

  • setInterval → 在事先定好的时间间隔内反复执行处理
  • setTimeout → 在指定的时间过后执行1次处理
【360页】

image

在指定的时间间隔内反复运行
在指定的时间过后运行一次

●setInterval/setTimeout方法

  试着将示例中的粗体字部分改为「setTimeOut」(①)。可以看到这一次在5000毫秒过后只显示了一次当前时间。
  setInterval/setTimeout方法都会返回用来唯一识别定时器的id值。可以将这个id值传递给clearInterval方法(setInterval时)/clearTimeout方法(setTimeout时)来取消定时器(②)。在这个例子中,点击[停止定时器],就会停止更新时间。

■setInterval/setTimeout方法的注意点
  虽然setInterval/setTimeout方法使用起来很简单,但也有应该注意的地方。下面,是主要的3点。
(1)不要在参数func中使用字符串
  也可以使用字符串给setInterval/setTimeout方法的参数func设定代码。

setTimeout('console.log("运行了!")', 500);

  但是,和eval方法(3.7.3)的理由相同,应该避免这样的写法。请一定要使用函数字面量来设定参数func。

(2)并不是在指定的时间(间隔)执行的
  虽然从「定时器」这个词来看可能会认为执行时间是准确的,但是setTimeout/setInterval方法的参数dur(时间间隔)并不能保证一定在这个时间运行。在setTimeout/setInterval方法中,只是在指定的时间内加入队列(执行处理的等待队伍)。如果队列中还有要执行的处理,就必须等待前面的处理结束。

【361页】

image

不能同时执行多个处理
(处理func)
其他的处理
3000毫秒
(处理func)
等其他的处理结束之后执行

●setTimeout方法不保证执行时间

(3)参数dur为零时
  下面这样的代码,会输出怎样的结果呢?

●清单7-03 interval_async.js image

console.log('abcde');
console.log('fghij');
console.log('klmno');
// 结果:???

  「因为参数dur为零,所以setTimeout方法的内容会立即执行,输出『abcde』『fghij』『klmno』」,但是正确答案是「abcde」「klmno」「fghij」。
  这是因为在将setTimeout方法的处理传递给定时器的过程中,JavaScript会继续执行后续的处理。这样的处理称为异步处理。
  利用这一点,可以书写像下面这样的代码。

setTimeout(function(){heavy();}, 0);
// 后续的处理

  假设heavy函数是某个繁重的处理。如果直接调用这个处理,后续的处理就不得不等待这个函数执行结束。但是,使用setTimeout方法使其异步,就可以不用等待heavy函数,并且因为后续的处理会先结束,所以可以让人感到运行速度提升了。

【362页】

Note setTimeout方法的限制
  确切地说,定时器中有最小延时的限制,调用间隔的最小值为4ms(如果设定值小于这个值,定时器就使用最小延时)。
  因为异步处理而使用0ms定时器时,如果可以确定客户端是现代浏览器,使用postMessage方法(7.4.5)代替会更合适。