-
setTimeOut
2019-09-16 09:05:37setTimeOut原理 上一次我在写 animation()函数的时候,说到了 setTimeOut的一些特点,这一次就是为了验证这些特点 setTimeOut 并不是在过了执行的时间(这个时刻)会立即触发,这个要看过了指定时间之后事件队列里...setTimeOut原理
- 上一次我在写 animation()函数的时候,说到了 setTimeOut的一些特点,这一次就是为了验证这些特点
- setTimeOut 并不是在过了执行的时间(这个时刻)会立即触发,这个要看过了指定时间之后事件队列里当前的事件是否是空,如果是,那么在那么时刻就会触发,如果不是,那么就是过了指定的时间之后,等待事件队列里当前的事件执行完才会触发
- 因此 setTimeOut可能会出现这种情况,过了指定时间之后不会立即出发,需要过了一会才会触发
测试 setTimeOut
var time = Date.now() setTimeout(()=>{ console.log(Date.now()-time) console.log("setTimeOut...") },300) console.log("ok...")
- 可以看见 过了指定时间之后,当前的事件队列为空,因此 setTimeOut可以在 300ms过后立即触发,但是如果将当前的事件数量增加了再来看看
var time = Date.now() setTimeout(()=>{ console.log(Date.now()-time) console.log("setTimeOut...") },300) // 2000 个 console.log("ok...") console.log("ok...")
- 可以看见这个时候已经不是300ms触发了,而是 764ms触发了
- 延迟函数 setTimeout() 相当于将延迟之后执行的事件(也就是异步事件,或者说将来要执行的事件插入到当前事件队列里的最末尾,至于在不在指定时间之后立即触发,就要看看那个之后事件队列里是不是为空,如果是,就会立即触发,如果不是,那么就要等待当前的事件队列为空才会执行)
-
setTimeout
2018-12-20 14:41:40教科书里面的setTimeout 定义很简单 setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。 广泛应用场景 定时器,轮播图,动画效果,自动滚动等等 上面一些应该是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秒后执行又是什么意思呢?是不是可以立即执行呢?
答案是不会的,setTimeout(fn,0)的含义是,指定某个任务在主线程最早可得的空闲时间执行,意思就是不用再等多少秒了,只要主线程执行栈内的同步任务全部执行完成,栈为空就马上执行。
setTimeout(function, 0)是有用的。它可以让callback作为另外一个事件响应代码来执行。实现了当前事件的代码执行完成之后,再渲染DOM,再执行setTimeout的callback。这样能够让一部分代码延后执行,并且在这之前渲染DOM。
0秒延迟,此回调将会放到一个能立即执行的时段进行触发。javascript代码大体上是自顶向下的,但中间穿插着有关DOM渲染,事件回应等异步代码,他们将组成一个队列,零秒延迟将会实现插队操作。
不写第二个参数,浏览器自动配置时间,在IE,FireFox中,第一次配可能给个很大的数字,100ms上下,往后会缩小到最小时间间隔,Safari,chrome,opera则多为10ms上下。上面答案来自《javascript框架设计》
关于setTimeout要补充的是,即便主线程为空,0毫秒实际上也是达不到的。根据HTML的标准,最低是4毫秒。有兴趣的话可以自行了解。
延伸:setTimeout有最小时间间隔限制,HTML5标准为4ms,小于4ms按照4ms处理,但是每个浏览器实现的最小间隔都不同。
setInterval的最短间隔时间是10毫秒,也就是说,小于10毫秒的时间间隔会被调整到10毫秒。好了,看了上面几个题目是不是感觉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还是必不可少的工具。实际项目运用:
函数去抖
让一个函数在一定间隔内没有被调用时,才开始执行被调用方法。比如当你在使用 google 搜索内容的时候,有些关键词输入到一半,谷歌会展示一个可选列表,根据你当前输入的内容作出的一个猜测联想。需要监听文字改变,每一次改变都会调用一次回调函数,现在需要的一种实现是在用户停止键盘事件一段时间后,去发送一个请求。
var debounce = function(method, context) { clearTimeout(method.tId); method.tId = setTimeout(function(){ method.call(context); },100); }
轮询任务
js中可以使用
setInterval
开启轮询,但是这种存在一个问题就是执行间隔往往就不是你希望的间隔时间。比如有个轮询任务间隔是100ms,但是执行方法的时间需要450ms,那么在200ms、300ms、400ms本来是计划中执行任务的时间,浏览器发现第一个还未执行完,那么就会放弃2、3、4次的任务执行,并且在500ms之后再次执行任务,这样的话,其实再次执行的间隔就只有50ms。使用setTimeout构造轮询能保证每次轮询的间隔。
setTimeout(function () { console.log('我被调用了'); setTimeout(arguments.callee, 100); }, 100);
延迟js引擎的调用
var div = document.createElement('div'); div.innerHTML = '我是一个div'; div.setAttribute('style', 'width:200px; height:200px;background-color:#f00; '); document.body.appendChild(div); setTimeout(function() { console.log('我被调用了'); }, 1000);
carousel.js
-
settimeout
2018-08-17 19:28:001、js中可以通过setTimeout函数设置定时器,让指定的代码在指定的时间运动. 如果我们希望在setTimeout之行前终止其运行就可以使用clearTimeout()。 2、clearTimeout()用于重置js定时器,如果你希望阻止setTimeout...一、概念
1、js中可以通过setTimeout函数设置定时器,让指定的代码在指定的时间运动. 如果我们希望在setTimeout之行前终止其运行就可以使用clearTimeout()。
2、clearTimeout()用于重置js定时器,如果你希望阻止setTimeout的运行,就可以使用clearTimeout方法。
setTimeout(要执行的代码,时间);
-
js中两种定时器,setTimeout和setInterval的区别
2017-03-31 09:22:03setTimeout只在指定时间后执行一次,代码如下: //定时器 异步运行 function hello(){ alert("hello"); } //使用方法名字执行方法 var t1 = window.setTimeout(hello,1000); var t2 = window.setTimeout("hello()",...setTimeout只在指定时间后执行一次,代码如下:
<script> //定时器 异步运行 function hello(){ alert("hello"); } //使用方法名字执行方法 var t1 = window.setTimeout(hello,1000); var t2 = window.setTimeout("hello()",3000);//使用字符串执行方法 window.clearTimeout(t1);//去掉定时器 </script>
setInterval以指定时间为周期循环执行,代码如下:
//实时刷新时间单位为毫秒 setInterval('refreshQuery()',8000); /* 刷新查询 */ function refreshQuery(){ $("#mainTable").datagrid('reload',null); }
两种方法根据不同的场景和业务需求择而取之,一般情况下setTimeout用于延迟执行某方法或功能,
setInterval则一般用于刷新表单,对于一些表单的假实时指定时间刷新同步
销毁两种定时器方法:
//清除Timeout的定时器,
传入id(创建定时器时会返回一个id) clearTimeout(i);
//清除Interval的定时器,
传入id(创建定时器时会返回一个id) clearInterval(j);
-
一篇文章彻底搞懂异步,同步,setTimeout,Promise,async
2019-06-10 13:18:14之前翻看别的大佬的博客看到了关于setTimeout,promise还有async执行顺序的文章。观看了几篇之后还是没有怎么看懂,于是自己开始分析代码,并整理了此文章,我相信通过此文章朋友们能对异步同步还有,setTimeout,... -
setTimeout 详解
2020-03-30 16:24:391. setTimeout 定义 setTimeout( )是属于 window 的 method, 但我们都是略去 window 这顶层物件名称, 这是用来设定一个时间, 时间到了, 就会执行一个指定的 method。 setTimeout()方法设置一个定时器,该定时器在... -
解决vue 使用setTimeout,离开当前路由setTimeout未销毁的问题
2020-10-15 02:23:34主要介绍了解决vue 使用setTimeout,离开当前路由setTimeout未销毁的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 -
setTimeout方法
2019-05-07 22:01:00SetTimeout方法 第一种写法↓ setTimeout方法是指在指定时间后执行一次指定函数。强调!只执行一次! ObjSetTimeout后面的window可以省略不写。SetTimeout后面的括号传入函数名称,注意只是传入名称不能有括号,... -
谈谈setTimeout
2018-08-03 17:56:59谈谈setTimeout 这段setTimeout代码什么意思? 我们一般说: 3秒后,会执行setTimeout里的那个函数 setTimeout(function(){ console.log('执行了') },3000) 但是这种说并不严谨,准确的解释是... -
settimeout使用
2018-12-19 10:18:32在前端页面写js方法时,经常会涉及到方法执行顺序的问题,这时用settimeout会解决一些简单地小问题, 不传参时格式: setTimeout(getAllRowsData, 200); 传参时: setTimeout(function () { getAllRowsData(0)... -
setTimeout详解
2018-03-31 19:08:51计时器setTimeout是我们经常会用到的,它用于在指定的毫秒数后调用函数或计算表达式。语法:setTimeout(code, millisec, args);注意:如果code为字符串,相当于执行eval()方法来执行code。当然,这一篇文章并不仅仅... -
setTimeout argument.callee
2015-09-10 22:11:04setTimeout -
react中settimeout_react 中使用setTimeout
2020-12-23 14:27:38React中使用setTimeoutsetTimeout做轮询React由于是在内存中运行,所以即使是DOM对象已经被销毁了,如果在组件卸载(componentWillUnmount)的时候没有清楚掉定时器, setTimeout做循环还是会在内存中一直运行... -
setTimeout 传参
2018-01-06 16:24:56function getProgress(name,type) { console.log(name+' : '+type) ...//setTimeout("getProgress(name,type)", 3000) //报错 setTimeout(getProgress.bind(null, 1), 4000); setTimeout(getProgress, 4000,1,'f'); s -
关于setTimeout
2017-07-02 19:41:311.setTimeout 0 有什么作用 setTimeout的作用是将代码推迟到指定时间执行,如果指定时间为0,setTimeout(f,0)那么会立刻执行吗? 答案是不会。setTimeout(f,0)将第二个参数设为0,作用是让f在现有的任务(当前脚本...