博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
setTimeout详解
阅读量:4651 次
发布时间:2019-06-09

本文共 2633 字,大约阅读时间需要 8 分钟。

一、setTimeout基础
setTimeout(func|code,delay);
第一个参数表示将要推迟的函数名或者一段代码,第二个参数表示推迟执行的毫秒数
 
eg:console.log(1);setTimeout('console.log(2)',1000);console.log(3);answer:132
 
*:推迟的代码必须以字符串的形式,因为引擎内部使用eval()函数,将字符串转为代码。
*:如果推迟执行的是函数,则可以直接将函数名,放入setTimeout()
 
eg:function func(){  console.log(2);}setTimeout(func,5000);//或者setTimeout(function(){  console.log(2);},1000)

 

*:如果写成setTimeout(func(),5000);func会立即执行

 

二、setTimeout支持更多的参数
eg:setTimeout(function(a,b){  console.log(a+b);},1000,4,5)//4,5 9//'str' '2' str2
 
*:从第三个参数开始,依次用来表示第一个参数(回调函数)传入的参数
*:一些古老的浏览器是不支持,可以用bind或apply方法来解决
 
eg:setTimeout(function(a,b){  console.log(a+b);}.bind(this,4,5),1000)
 
*:第一个参数表示将原函数的this绑定全局作用域,第二个参数开始是要传入原函数的参数
*:当调用绑定函数时,绑定函数会以创建它时传入bind()方法的第一个参数作为 this
 
三、setTimeout()中回调函数中的this
eg:var a=1;var obj={  a:2,  b:function(){    setTimeout(function(){      console.log(this.a);    },2000);  }};obj.b();
 
上面代码输出的是1,而不是2,表示o.b的this所指向的已经不是o,而是全局环境了
可以用bind()来改变这个情况:
 
var a=1;var obj={    a:2,    b:function(){        setTimeout(function(){            console.log(this.a);        }.bind(this),2000);//注意这行    }};obj.b();

 

四、setTimeout()执行回调间隔时间长度
 
var startTime = new Date();setTimeout(function () {    console.log(new Date() - startTime);}, 100);
 
//100+ 取决于后面同步执行的JS需要占用多少时间
 
 
五、setTimeout(func,0)
eg:func1和func2谁会先执行?function func1(){    console.log(1);}function func2(){    console.log(2);}setTimeout(function () {    func1();}, 0)func2();

 

setTimeout(function(){    func1()},0)setTimeout(function(){    func1();})

有什么差别?

0秒延迟,此回调将会放到一个能立即执行的时段进行触发。javascript代码大体上是自顶向下的,但中间穿插着有关DOM渲染,事件回应等异步代码,他们将组成一个队列,零秒延迟将会实现插队操作。
不写第二个参数,浏览器自动配置时间,在IE,FireFox中,第一次配可能给个很大的数字,100ms上下,往后会缩小到最小时间间隔,Safari,chrome,opera则多为10ms上下。
 
 
 
六、setTimeout和单线程
首先需要注意javascript是单线程的,特点就是容易出现阻塞。如果一段程序处理时间很长,很容易导致整个页面hold住。什么交互都处理不了怎么办?
setTimeout一个很关键的用法就是分片,如果一段程序过大,我们可以拆分成若干细小的块。
例如上面的情况,我们将那一段复杂的逻辑拆分处理,分片塞入队列。这样即使在复杂程序没有处理完时,
我们操作页面,也是能得到即使响应的。其实就是将交互插入到了复杂程序中执行。
换一种思路,上面就是利用setTimeout实现一种伪多线程的概念
有个函数库Concurrent.Thread.js 就是实现js的多线程的
eg:Concurrent.Thread.create(function(){    for(var i=0; i<100000000; i++){        console.log(i);    }})$('#test').click(function(){    alert(1);});
虽然有个巨大的循环,但是这时不妨碍你去触发alert();
当我们需要渲染一个很复杂的DOM时,例如table组件,复杂的构图等等,
假如整个过程需要3s,我们是等待完全处理完成在呈现,还是使用一个setTimeout分片,
将内容一片一片的断续呈现。
其实setTimeout给了我们很多优化交互的空间。
 
 
七、如何使用
setTimeout这么厉害,那么我们是需要在在项目中大量使用吗?
我这边的观点是非常不建议,在我们业务中,基本上是禁止在业务逻辑中使用setTimeout的
例如,当一个实例还没有初始化的前,我们就使用这个实例,错误的解决办法是使用实例时加个setTimeout,确保实例先初始化。
为什么错误?这里其实就是使用hack的手段
第一是埋下了坑,打乱模块的生命周期
第二是出现问题时,setTimeout其实是很难调试的。
综上,setTimeout其实想用好还是很困难的,时间的不确定性,排队运算混乱, 他更多的出现是在框架和类库中,例如一些实现Promis的框架,就用上了setTimeout去实现异步。

 

转载于:https://www.cnblogs.com/wzndkj/p/7069331.html

你可能感兴趣的文章
MPI 环境搭建问题-运行程序闪退
查看>>
(数据科学学习手札05)Python与R数据读入存出方式的总结与比较
查看>>
面向对象课程 - 寒假第三次作业 - C++计算器项目初始部分
查看>>
Java私塾的一些基础练习题(一)
查看>>
Shell 07 项目案例
查看>>
Dapper基础用法
查看>>
一步步学习SPD2010--第九章节--使用可重用工作流和工作流表单(1)--创建和使用可重用工作流...
查看>>
Network 第六篇 - 三层交换机配置路由功能
查看>>
OSL LLVM 3.3 Related Changes
查看>>
1.4 99乘法表
查看>>
雇佣K个工人的最小费用 Minimum Cost to Hire K Workers
查看>>
mysql优化方法
查看>>
[转]【HttpServlet】HttpServletResponse接口 案例:完成文件下载
查看>>
Eclipse配置默认的编码集为utf-8
查看>>
初学Python
查看>>
rman 脚本备份全过程
查看>>
图像处理笔记(十八):模板匹配
查看>>
Educational Codeforces Round 60 D. Magic Gems
查看>>
c# 保存和打开文件的方法
查看>>
调用图灵机器人API实现简单聊天
查看>>