setTimeout与setInterval(一)

一. setTimeout

1. 定义

window.setTimeout(func,[delay,param1,param2,····]);
window.setTimeout(code,[delay]);

参数说明:
a. 对于第一行代码:
func指的是延迟后想执行的函数,delay为延迟秒数,为毫秒,最大为32位有符号整数值,超过最大值即2147483647,将致使函数被当即执行。
param是func的参数,可是这种赋予参数的方法在IE9如下(含IE9)不兼容,可使用polyfill或者外层包裹进行兼容性处理,有兴趣能够点击这里
b. 对于第二行代码:
code指的是可执行代码,例如javascript

setTimeout(alert("HeiHei"),200)

可是这种方法不推荐,相似eval(),能够包含可执行代码,含有安全隐患。html

2. 事件添加的说明

定时器对队列的工做方式:当特定时间过去后将代码添加到队列中,但并不意味着会立刻将执行,设定一个200ms后执行的定时器,指的是在200ms后它将被添加到队列中,是否执行,还得看队列中是否没有其余的东西。看一下例子:html5

var a=document.getElementById("nav");
    a.onclick=function(){
    setTimeout(alertsomething,200);
    //一些其余的代码
}
function alertsomething(){
    alert("it is working");
}

假定onclick处理程序须要执行300ms,这时虽然在205ms添加了定时器代码,可是仍旧须要等待onclick事件完成后才可以执行。如图所示,原本在205ms处添加了定时器代码,可是因为此时onclick事件还没结束,故要等到300ms后才执行定时器代码
javascript 进程时间线java

3. 清除事件

window.clearTimeout(timeoutID);

4. 对于this的影响

setTimeout调用的代码,运行在与所在函数彻底分离的执行环境上,在非严格模式中,this默认指向global或window,严格模式中会抛出undefined,经过call的方式目前也没法改变,官方的示例以下:chrome

myArray = ["zero", "one", "two"];
myArray.myMethod = function (sProperty) {
    alert(arguments.length > 0 ? this[sProperty] : this);
};
setTimeout.call(myArray, myArray.myMethod, 2000); // error: "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object"
setTimeout.call(myArray, myArray.myMethod, 2500, 2); // same error

对此咱们可使用外加一个匿名函数解决。浏览器

setTimeout(function(){myArray.myMethod()}, 2000); // prints "zero,one,two" after 2 seconds
setTimeout(function(){myArray.myMethod('1')}, 2500); // prints "one" after 2.5 seconds

其余解决方案能够参照一下参考资料。安全

5. 事件延迟时间大于设定值

a.上文图中所示,队列中还有事件未执行完成,须要等待
b.chrome和firefox在未激活的标签中,会减缓setTimeoutsetInterval的执行,具体缘由能够参考下文的资料
c.因为浏览器精度的缘由,delay的值最终大于等于4。app

下面是w3c中的原文:less

If the currently running task is a task that was created by the setTimeout() method, and timeout is less than 4, then increase timeout to 4.函数

举个例子:

setTimeout(function() {
            alert(2);
        }, 0);
        alert(1); //先显示1,接着才显示2

2、setInterval

1.定义

跟setTimeout相似

window.setInterval(func, delay[,param1, param2, ...]);
window.setInterval(code, delay);

为了不多个定时器代码不间断连续运行好几回,当使用setInterval(),仅当没有该定时器的任何其余代码实例时,才将定时器代码添加到队列中,通俗点就是等到上个定时器完成,再添加一个。

2.缺点

  1. 某些间隔会被跳过

  2. 多个定时器的代码执行之间的间隔可能会比预期小。

图片描述

在5处,建立一个定时器
205处,添加一个定时器,可是onclick代码没执行完成,等待
300处,onclick代码执行完毕,执行第一个定时器
405处,添加第二个定时器,但前一个定时器没有执行完成,等待
605处,原本是要添加第三个定时器,可是此时发现,队列中有了一个定时器,被跳过
等到第一个定时器代码执行完毕,立刻执行第二个定时器,因此间隔会比预期的小。

3.解决方法

链式调用,以下图所示,主要用于重复定时器

setTimeout(function(){
    //处理代码
    setTimeout(arguments.callee,interval)
},intercal);

递归调用本身。

4. 清除事件

window.clearInterval(intervalID)

3、二者之间的区别

setTimeout方法,在一个指定的时间间隔后运行代码。
setInterval方法, 每隔一个固定的时间间隔后持续运行指定代码。

4、参考资料

  1. MDN WindowTimers.setTimeout()

  2. W3C Times

  3. Chrome and Firefox throttle setTimeout/setInterval in inactive tabs

  4. 《JavaScript高级程序设计》Nicholas C.Zakas著 李松峰 曹力译

  5. 你真的了解setTimeout和setInterval吗

相关文章
相关标签/搜索