setTimeout笔记

JavaScript,前端 2017-11-11

setTimeout()是什么?

嗯,它是一个定时器。我最基础的了解是这样的,就是我们设置一个时间,等这个时间到了,就执行一个函数或者一段代码。

Syntax 语法

//  必要参数 function,可选参数 时间,形参
var timeoutID = scope.setTimeout(function[, delay, param1, param2, ...]);
//  必要参数 function,可选参数 时间
var timeoutID = scope.setTimeout(function[, delay]);
//  必要参数 code代码段,可选参数 时间
var timeoutID = scope.setTimeout(code[, delay]);

时长是以毫秒为单位的,默认为0,0则立即执行,但肯定有延迟。

不一定是立即执行,肯定会有延迟。
浏览器是单线程的,是基于事件循环的,所以是以队列去执行的,setTimeout会放入到一个特殊的队列。

setTimeout(function() {
    console.log('this is setTimeout');
}, 0);
var test = 'this is a text string';
console.log(test);
// this is a text string
// this is setTimeout

你会发现setTimeout执行慢于console.log
是因为只有当浏览器当前队列有空闲的时候才去执行位于特殊队列里的setTimeout

另外现代浏览器也有做限制,可能是简单易用,所以出现了滥用。当有大量嵌套调用,回调一定次数后会有一定的延迟限制。

setTimeout执行完返回值是一个整形,是一个timeoutID,不是固定值,可以使用clearTimeout()清除定时器。

一开始使用定时器时,一般都是在轮播图用到。他们都会这样写:

var timer = setTimeout(function(){
    // 可能就又调用setTimeout了
    // 结束的时候用clearTimeout(timer)
}, 2000);

之前一直不怎么懂为什么要这样,为什么这样就可以清除定时器了。
原来,定时器执行完后会返回一个id,根据这个id去识别不同的定时器,然后clearTimeout()传入定时器id就可以清除了。

var timeout1 = setTimeout(function() {
    //
}, 1000);

var timeout2 = setTimeout(function() {
    //
}, 1000);

var timeout3 = setTimeout(function() {
    //
}, 1000);

console.log('timeout1---', timeout1);
console.log('timeout2---', timeout2);
console.log('timeout3---', timeout3);

// timeout1--- 1
// timeout2--- 2
// timeout3--- 3

不建议传入一段可执行代码,尽量使用传入一个function去执行

如果传入的是一段代码的话,其实就类似于eval()就会有不安全等问题出现。
另外可能会造成内存泄漏。

setTimeout(function test1() {
    var a = 1;
    console.log(a);
}, 0)

setTimeout((function test2() {
    var b = 1;
    console.log(b);
}).toString(), 0)

test1
// Uncaught ReferenceError: test1 is not defined
test2
// ... (打印出 test2 的函数体)

test2能被调用到,所以它执行完并没有被销毁,这样就会一直占用内存,所以称为内存泄漏

可以实现简单的异步执行效果

我们把一些耗时的代码丢到setTimeout回调里头,然后不给delay,默认就为0,所以当浏览器有空闲的时候才会去执行它。

但还是少用吧,毕竟我们有更优解去实现异步,比如Promise

参考资料


本文由 阿涛 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

还不快抢沙发

添加新评论