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

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

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

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

  1. var intervalTimer=setInterval(function(){
  2. console.log(1)
  3. },3000);
  4. console.log(intervalTimer); //一般是一个数字,Number
  5. button.onclick=function(){
  6. clearInterval(intervalTimer);
  7. };

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

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

  1. var a=1;
  2. var obj={
  3. a:2,
  4. b:function(){
  5. setTimeout(function(){
  6. console.log(this.a);//这里返回的是:1;
  7. },2000);
  8. }
  9. };
  10. obj.b();

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

  1. var a=1;
  2. var obj={
  3. a:2,
  4. b:function(){
  5. setTimeout(function(){
  6. console.log(this.a);//这里返回的是:2;
  7. }.bind(this),2000);//注意这行
  8. }
  9. };
  10. obj.b();

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

关于setInterval()和setTimeout()的参数

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

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

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

  1. setTimeout(function(a,b){
  2. console.log(1+a+b);//这里打印的是:8
  3. },1000,3,4);

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

关于clearInterval()和clearTimeout()

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

  1. var intervalTimer=setInterval(function(){
  2. console.log(1)
  3. },3000);
  4. console.log(intervalTimer);
  5. button.onclick=function(){
  6. clearTimeout(intervalTimer); //注意这里,不是clearInterval哦
  7. };

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

教科书里面的setTimeout

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

广泛应用场景
定时器,轮播图,动画效果,自动滚动等等

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

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

测试题

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

  1. var startTime = new Date();
  2. setTimeout(function () {
  3. console.log(new Date() - startTime);
  4. }, 100)

请问最后打印的是多少?
我觉得正确答案是,取决于后面同步执行的js需要占用多少时间。
MAX(同步执行的时间, 100)

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

  1. setTimeout(function () {
  2. func1();
  3. }, 0)
  4. func2();

func1和func2谁会先执行?

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

再来一题

  1. setTimeout(function () {
  2. func1()
  3. }, 0)

  1. setTimeout(function () {
  2. func1()
  3. })

有什么差别?

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

  1. Concurrent.Thread.create(function(){
  2. for (var i = 0;i<1000000;i++) {
  3. console.log(i);
  4. };
  5. });
  6. $('#test').click(function () {
  7. alert(1);
  8. });

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

是不是很厉害~

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

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

如何使用

setTimeout这么厉害,那么我们是需要在在项目中大量使用吗?
我这边的观点是非常不建议,在我们业务中,基本上是禁止在业务逻辑中使用setTimeout的,因为我所看到的很多使用方式都是一些问题不好解决,setTimeout作为一个hack的方式。
例如,当一个实例还没有初始化的前,我们就使用这个实例,错误的解决办法是使用实例时加个setTimeout,确保实例先初始化。
为什么错误?这里其实就是使用hack的手段
第一是埋下了坑,打乱模块的生命周期
第二是出现问题时,setTimeout其实是很难调试的。

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

综上,setTimeout其实想用好还是很困难的, 他更多的出现是在框架和类库中,例如一些实现Promis的框架,就用上了setTimeout去实现异步。
所以假如你想去阅读一些源码,想去造一些轮子,setTimeout还是必不可少的工具。

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

  1. 你所不知道的setTimeout

    JavaScript提供定时执行代码的功能,叫做定时器(timer),主要由setTimeout()和setInterval()这两个函数来完成.它们向任务队列添加定时任务.初始接触它的人都觉得好简单 ...

  2. 关于setTimeout()你所不知道的地方

    前言:看了这篇文章,1.注意setTimeout引用的是全部变量还是局部变量了,当直接调用外部函数方法时,实际上函数内部的变量已经变成全 局.2.提醒我防止出错的,用匿名函数不容易出错.3.setTi ...

  3. setTimeout的核心原理和巧用

    你所不了解的setTimeout 发表于 2015年11月23日 by 愚人码头 被浏览 14,756 次 分享到: 0 小编推荐:掘金是一个高质量的技术社区,从 ECMAScript 6 到 Vue ...

  4. 关于setTimeout()你所不知道的地方,详解setTimeout()

    关于setTimeout()你所不知道的地方,详解setTimeout() 前言:看了这篇文章,1.注意setTimeout引用的是全部变量还是局部变量了,当直接调用外部函数方法时,实际上函数内部的变 ...

  5. 你所不知道的setInterval

    在你所不知道的setTimeout记载了下setTimeout相关,此篇则整理了下setInterval:作为拥有广泛应用场景(定时器,轮播图,动画效果,自动滚动等等),而又充满各种不确定性的这set ...

  6. 以setTimeout来聊聊Event Loop

    平时的工作中,也许你会经常用到setTimeout这个方法,可是你真的了解setTimeout吗?本文想通过总结setTimeout的用法,顺便来探索javascript里面的事件执行机制. setT ...

  7. 定时器(setTimeout)的秘密

    原文地址:→传送门 写在前面 setTimeout()是大家再熟悉不过的定时器,但平时对定时器的了解甚少,于是想看看setTimeout()的原理机制. setTimeout()基础 setTimeo ...

  8. 【原】以setTimeout来聊聊Event Loop

    平时的工作中,也许你会经常用到setTimeout这个方法,可是你真的了解setTimeout吗?本文想通过总结setTimeout的用法,顺便来探索javascript里面的事件执行机制. setT ...

  9. 你所不知道的 CSS 阴影技巧与细节 滚动视差?CSS 不在话下 神奇的选择器 :focus-within 当角色转换为面试官之后 NPOI 教程 - 3.2 打印相关设置 前端XSS相关整理 委托入门案例

    你所不知道的 CSS 阴影技巧与细节   关于 CSS 阴影,之前已经有写过一篇,box-shadow 与 filter:drop-shadow 详解及奇技淫巧,介绍了一些关于 box-shadow  ...

随机推荐

  1. ocLazyLoad angular 按需加载

    ionic 框架 1.引用 index.html 加载 <script type="text/javascript" src="lib/oclazyload/ocL ...

  2. mysql查询结果导出到文件

    方法一: 直接执行命令: mysql> select count(1) from table   into outfile '/tmp/test.xls'; Query OK, 31 rows ...

  3. unity3d Light Probe Group图解超详细使用方法

    原创文章如需转载请注明:转载自http://blog.csdn.net/qq617119142 第一步,创建一个Panel 和 三个 cube,搭建成如下图形状 第二步,创建2个点光源,一个为绿灯,一 ...

  4. fiddler,https抓包设置

    1.fiddler 2 汉化版本不支持https证书下载,需要下载fiddler 4版本进行验证 若fiddler 2版本,可能存在无法访问Pc端fiddler返回页面,无法下载证书 2.打开Fidd ...

  5. SPSS数据分析——t检验

    SPSS中t检验全都集中在分析—比较均值菜单中.关于t检验再简单说一下,我们知道一个统计结果需要表达三部分内容,即集中性.变异性.显著性. 集中性的表现指标是均值变异的的表现指标是方差.标准差或标准误 ...

  6. 使用实时文件夹显示ContentProvider的数据

    所谓实时文件夹(即LiveFolder),是指用于显示ContentProvider提供的数据的桌面组件. ContentProvider用于向外提供数据访问的接口,一个应用程序可通过ContentP ...

  7. Scala深入浅出实战经典---001-Scala开发环境搭建和HelloWorld解析

    001-Scala开发环境搭建和HelloWorld解析 Scala 函数式编程和面向对象结合的语言 函数式编程擅长数值计算 面向对象擅长大型工程和项目的组织以及团队的分工协作 Scala会是下一个伟 ...

  8. Enable SSHD on Ubuntu

    https://help.ubuntu.com/community/SSH/OpenSSH/Configuring

  9. 团队开发——冲刺2.a

    冲刺阶段二(第一天) 1.今天准备做什么? 收集游戏图片:开始.暂停.继续.重新开始.退出……为了界面的后期美工做准备. 2.遇到什么困难? 网上的图片很多,但是比较难找到统一风格的.

  10. 简单poi读取excel

    1.添加依赖jar包 maven配置: <!-- poi being --> <dependency> <groupId>org.apache.poi</gr ...