你所不了解的setTimeout

看到了一篇不错的文章《你会用setTimeout吗 》,转载过来的,改了个名字,一下子感觉搞大上了,嘎嘎。

加了几个关于 setTimeout 和setInterval的小知识:

关于setInterval()和setTimeout()返回值

setInterval(),setTimeout() 会返回一个值,一般认为是ID,将这个ID值传递给clearInterval(),clearTimeout() 可以取消执行,例如:

var intervalTimer=setInterval(function(){

    console.log(1)

},3000);

console.log(intervalTimer); //一般是一个数字,Number

button.onclick=function(){

    clearInterval(intervalTimer);

};

关于setInterval()和setTimeout()中回调函数中的this

setInterval(),setTimeout() 方法是浏览器 window 对象提供,所以第一个参数函数中的this指向window对象,这跟变量的作用域有关:

var a=1;

var obj={

    a:2,

    b:function(){

        setTimeout(function(){

            console.log(this.a);//这里返回的是:1;

        },2000);

        

    }

};

obj.b();

当然你可以通过使用bind()方法来改变这个情况:

var a=1;

var obj={

    a:2,

    b:function(){

        setTimeout(function(){

            console.log(this.a);//这里返回的是:2;

        }.bind(this),2000);//注意这行

    }

};

obj.b();

关于bind()方法,你可以看这里:http://www.css88.com/archives/5611

关于setInterval()setTimeout()的参数

大家都知道setInterval()和setTimeout()可以接收两个参数,第一个参数是需要回调的函数,必须传入的参数,第二个参数是时间间隔,毫秒数,可以省略,这个可以看文章的下面,

不传第二个参数,浏览器自动配置时间,在IE,FireFox中,第一次配可能给个很大的数字,100ms上下,往后会缩小到最小时间间隔,Safari,chrome,opera则多为10ms上下。

但是我要说的当然不是这个,我要说的是setInterval()和setTimeout()可以接收更多的参数,那么这些参数是干什么用的呢?从第三个参数开始,依次用来表示第一个参数(回调函数)传入的参数,例如:

setTimeout(function(a,b){

   console.log(1+a+b);//这里打印的是:8

},1000,3,4);

当然一些古老的浏览器是不支持的。

关于clearInterval()和clearTimeout()

clearInterval()和clearTimeout()其实是通用的,就是说你可以用 clearInterval() 取消 setTimeout() 执行,clearTimeout()同样可以取消 setInterval() 执行。

var intervalTimer=setInterval(function(){

    console.log(1)

},3000);

console.log(intervalTimer); 

button.onclick=function(){

    clearTimeout(intervalTimer); //注意这里,不是clearInterval哦

};

=============== 以下内容来源: 你会用setTimeout吗  ===================

教科书里面的setTimeout

定义很简单

setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。

广泛应用场景

定时器,轮播图,动画效果,自动滚动等等

上面一些应该是setTimeout在大家心中的样子,因为我们平常使用也不是很多。

但是setTimeout真的有那么简单吗?

测试题

一个题目,如果你在一段代码中发现下面内容

var startTime = new Date();

setTimeout(function () {

    console.log(new Date() - startTime);

}, 100)

请问最后打印的是多少?

我觉得正确答案是,取决于后面同步执行的js需要占用多少时间。

MAX(同步执行的时间, 100)。

再加一个题目,只有下面代码

setTimeout(function () {

    func1();

}, 0)

func2();

func1和func2谁会先执行?

这个答案应该比较简单,func2先执行,func1后面执行。

再来一题

setTimeout(function () {

    func1()

}, 0)

setTimeout(function () {

    func1()

})

有什么差别?

0秒延迟,此回调将会放到一个能立即执行的时段进行触发。javascript代码大体上是自顶向下的,但中间穿插着有关DOM渲染,事件回应等异步代码,他们将组成一个队列,零秒延迟将会实现插队操作。

不写第二个参数,浏览器自动配置时间,在IE,FireFox中,第一次配可能给个很大的数字,100ms上下,往后会缩小到最小时间间隔,Safari,chrome,opera则多为10ms上下。

上面答案来自《javascript框架设计》

好了,看了上面几个题目是不是感觉setTimeout不是想象中那样了。

setTimeout和单线程

下面是我自己的一些理解

首先需要注意javascript是单线程的,特点就是容易出现阻塞。如果一段程序处理时间很长,很容易导致整个页面hold住。什么交互都处理不了怎么办?

简化复杂度?复杂逻辑后端处理?html5的多线程?

上面都是ok的做法,但是setTimeout也是处理这种问题的一把好手。

setTimeout一个很关键的用法就是分片,如果一段程序过大,我们可以拆分成若干细小的块。

例如上面的情况,我们将那一段复杂的逻辑拆分处理,分片塞入队列。这样即使在复杂程序没有处理完时,我们操作页面,也是能得到即使响应的。其实就是将交互插入到了复杂程序中执行。

换一种思路,上面就是利用setTimeout实现一种伪多线程的概念。

有个函数库Concurrent.Thread.js 就是实现js的多线程的。

一个简单使用的例子,引入Concurrent.Thread.js后

Concurrent.Thread.create(function(){

    for (var i = 0;i<1000000;i++) {

        console.log(i);

    };

});

$('#test').click(function  () {

    alert(1);

});

虽然有个巨大的循环,但是这时不妨碍你去触发alert();

是不是很厉害~

还有一种场景,当我们需要渲染一个很复杂的DOM时,例如table组件,复杂的构图等等,假如整个过程需要3s,我们是等待完全处理完成在呈现,还是使用一个setTimeout分片,将内容一片一片的断续呈现。

其实setTimeout给了我们很多优化交互的空间。

如何使用

setTimeout这么厉害,那么我们是需要在在项目中大量使用吗?

我这边的观点是非常不建议,在我们业务中,基本上是禁止在业务逻辑中使用setTimeout的,因为我所看到的很多使用方式都是一些问题不好解决,setTimeout作为一个hack的方式。

例如,当一个实例还没有初始化的前,我们就使用这个实例,错误的解决办法是使用实例时加个setTimeout,确保实例先初始化。

为什么错误?这里其实就是使用hack的手段

第一是埋下了坑,打乱模块的生命周期

第二是出现问题时,setTimeout其实是很难调试的。

我认为正确的使用方式是,看看生命周期(可参考《关于软件的生命周期 》),把实例化提到使用前执行。

综上,setTimeout其实想用好还是很困难的, 他更多的出现是在框架和类库中,例如一些实现Promis的框架,就用上了setTimeout去实现异步。

所以假如你想去阅读一些源码,想去造一些轮子,setTimeout还是必不可少的工具。

时间: 2024-11-03 06:13:25

你所不了解的setTimeout的相关文章

javascript-急!!!!求大神!js中如何把setTimeout的时间写活?

问题描述 急!!!!求大神!js中如何把setTimeout的时间写活? 我这里有一个算法,但是每次调用后会根据不同的需要所耗费的时间不同, 然后我要写一个绑定事件来反复调用这个函数,如果把时间写死,有的算法很快会浪费时间,但是也有的算法会执行不完,如何才能根据不同的需要把算法正好执行完后再执行之后的内容... 解决方案 算法有返回值没有,有的话判断一下,如果执行完成,则再次调用函数. 解决方案二: 虽然不太清楚,你的需求是什么.但是你所说的改变setTimeout的时间来处理你现在所遇到的问题

从setTimeout谈JavaScript运行机制

前言 最近在看些JavaScript异步的东西,但是由于时间有限,才刚看了个头,不得不中途停止.为了方便日后查阅以备重拾,遂记录一点体会,如果能使得他人有所收获,那更是极好的.其实本文与异步并没有太大关系. 从setTimeout说起 众所周知,JavaScript是单线程的编程,什么是单线程,就是说同一时间JavaScript只能执行一段代码,如果这段代码要执行很长时间,那么之后的代码只能尽情地等待它执行完才能有机会执行,不像人一样,人是多线程的,所以你可以一边观看某岛国动作片,一边尽情挥洒汗

Javascript异步编程之setTimeout与setInterval详解分析(一)

  在谈到异步编程时,本人最主要会从以下三个方面来总结异步编程(注意:特别解释:是总结,本人也是菜鸟,所以总结不好的,请各位大牛多多原谅!)       1. setTimeout与setInterval详细分析基本原理.       2. 分布式事件(pub/sub).       3. Promise对象和Deferred对象.       接下来这篇博客会总结setTimeout和setInterval基本点,对于上面三点会分三篇博客分别来总结,对于知道上面三点的人,但是又不是非常 了解全

js 传递函数: JS中setInterval、setTimeout不能传递带参数的函数的解决办法

在JS中无论是setTimeout还是setInterval,在使用函数名作为调用句柄时都不能带参数,而在许多场合必须要带参数,这就需要想方法解决.一.采用字符串形式:--(缺陷)参数不能被周期性改变setInterval("foo(id)",1000);二.匿名函数包装 (推荐)window.setInterval(function()    {foo (id);    }, 1000);   这样就可以周期性执行foo(id)这个函数,而且把变量id传递进去:三.定义返回无参函数的

setTimeout()方法title属性制作动态标题栏

文章简介:动态标题栏实现的主要技术是document对象的title属性来修改页面标题栏中的信息,并用window对像的setTimeout()方法对title属性中的信息以指定间隔时间进行修改.下面对setTimeout方法进行简单介绍. 动态标题栏实现的主要技术是document对象的title属性来修改页面标题栏中的信息,并用window对像的setTimeout()方法对title属性中的信息以指定间隔时间进行修改.下面对setTimeout方法进行简单介绍. 语法:setTimeout

setTimeout 和 setInterval 的区别

区别 window对象有两个主要的定时方法,分别是setTimeout 和 setInteval  他们的语法基本上相同,但是完成的功能取有区别. setTimeout方法是定时程序,也就是在什么时间以后干什么.干完了就拉倒. setInterval方法则是表示间隔一定时间反复执行某操作. 如果用setTimeout实现setInerval的功能,就需要在执行的程序中再定时调用自己才行.如果要清除计数器需要 根据使用的方法不同,调用不同的清除方法: 例如:tttt=setTimeout('nor

SetTimeOut方法用法示例

示例 (一).示例图片效果 (二).代码 <html><head><title>window.setTimeout()函数</title><script laguage="javascript"><!--function showtime(){mytime=new Date();mytime=mytime.getHours()+":"+mytime.getMinutes()+":"

setTimeout 的用法详细介绍

例子:<SCRIPT>var g_oToHide = null;function fnHide(oToHide){g_oToHide = oToHide;window.setTimeout(fnHide2, 3000);}function fnHide2(sID){if (g_oToHide) {g_oToHide.style.display="none";}}</SCRIPT><INPUT TYPE=button VALUE="Now you

学习Flash8中的setTimeout函数的用法

函数 在Flash8中,有个未公开的函数setTimeout,执行功能就是在设定的时间到了以后,调用一次设定的函数. 这样对于只需要调用一次的时间触发事件,我们再也不需要用 setInterval 函数配合  clearInterval 函数来处理了.  很好用,该函数属于未公开的函数的原因,很大可能是因为在flash 8.5中属于非推荐语法,所以隐藏了. 用法: function openWebsite(url:String) { getURL(url, "_blank");}web