Contents
  1. 1. Forword
  2. 2. 间歇调用
  3. 3. 超时调用
  4. 4. 结论
  5. 5. else
  6. 6. 关于性能

Forword

关于超时调用与间歇调用的API不再累述。本文主要讨论性能问题

间歇调用

常见用法如下:

1
2
3
4
5
6
7
8
9
10
11
var num = 0,
max = 10,
intervalId = null
function incrementNumber() {
num++
if (num == max) {
clearInterval(intervalId)
alert("Done")
}
}
intervalId = setInterval(incrementNumber, 500)

该方法返回一个间歇调用ID,如果不加干涉,该方法会一直重复调用直到页面卸载,取消间歇调用的重要性远远高于取消超时调用。
另外,无法根据需要直接更改间歇调用的时间间隔,只能通过“重新启动”的方法进行参数修正。
在实际过程中,一个间歇调用很有可能在另一个间歇调用结束前启动这源于间歇调用在“0时刻”会执行代码的特点

超时调用

下面是利用超时调用模拟间歇调用的方法

1
2
3
4
5
6
7
8
9
10
11
var num = 0,
max = 100
function incrementNumber() {
num++
if(num < max){
setTimeout(incrementNumber, 500)
} else {
alert("Done")
}
}
setTimeout(incrementNumber, 500)

该方法使用时可以发现,没有必要追踪超时调用ID,因为执行代码后调用将会停止,因此减少了一个参数。由于是延迟执行,超时调用也不存在上述问题。甚至可以给函数传入参数来直接修改间隔时间

结论

除了某些代码简单情况下,最好不要使用间歇调用

else

理论上字符串代码块

1
setInterval("alert('mukyu')", 10000)

是可以执行的,但是尽量避免这种写法,因为代码超过1行后涉及到解析问题。特别对于我这种无分号党

老老实实用函数吧

1
2
3
4
5
6
7
8
function Patchouli() {
alert("mukyu!")
}
setInterval(Patchouli, 10000)
//两个以上函数或带参数用匿名函数写法
setInterval(function(){
Patchouli()
}, 10000)

关于性能

随着对JavaScript了解的深入,觉得有必要在阐述几点。

———————————————————————-7.24更新———————————————————————-

  • setTimeout
    此方法不是js的原始方法,事实上通过纯JavaScript写不出setTimeout这个方法。虽然可以通过window.setTimeout调用它。
  • JavaScript事件队列
    setTimeout(someFuc, interval)实际上并不是过了interval时间后,执行someFuc,而是过了interval时间后,把someFuc加入事件队列中。因为JavaScript是单线程的,它一次只能执行一个事件。实际上任何JavaScript代码都不是立即执行的,只能说是在空闲的时候尽快执行
    举个例子:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    var btn = document.getElementById("my-btn");
    btn.onclick = function(){
    setTimeout(function(){
    document.getElementById("message").style.visibility = "visible";
    }, 250);
    // TODO:
    }

首先假如onclick事件处理了300ms,那么定时器里的代码至少要在定时器设置之后的300ms才会被执行。假如在255ms时队列添加了定时器代码,但这时候并不能执行,因为onclick还未结束。

同理setInterval确保了定时器代码规则地插入队列中。机制的JavaScript为了防止代码鬼畜,仅当没有该定时器的其他代码实例时,才将代码添加到队列中。这确保了最小的时间间隔为指定间隔。

然而机制的JS规则会带来几个问题:1)setInterval会漏拍;2)当存在两个或以上的setInterval时,间隔会比预期的小。为了避免这两个缺陷,我们使用之前提到的链式setTimeout来解决这个问题。

1
2
3
4
5
6
7
8
setTimeout(function(){
// TODO:
// your suck code
if(someLimit){
setTimeout(arguments.callee, 250);
}
},250);

作为一个性能党,我已经好好的加分号了,虽然快不了多少,聊胜于无吧。
以上。

Contents
  1. 1. Forword
  2. 2. 间歇调用
  3. 3. 超时调用
  4. 4. 结论
  5. 5. else
  6. 6. 关于性能