资讯专栏INFORMATION COLUMN

js 定时器笔记

BoYang / 2011人阅读

摘要:本文是学习定时器单线程同步异步任务的笔记,只适合初学者。第一个参数是函数名或者语句,第二个参数延迟的时间参数,单位为它返回定时器的编号,以后可以用来取消这个定时器。将该整数传入和函数,就可以取消对应的定时器。

本文是学习js定时器、单线程、同步异步任务的笔记,只适合初学者。

一、定时器(timer)

JavaScript提供定时执行代码的功能,该功能主要由setTimeout()和setInterval()这两个函数来实现

二、setTimeout() 1、使用规则

setTimeout函数用来指定某个函数或某段代码,在多少毫秒之后执行。
第一个参数是函数名或者语句,第二个参数延迟的时间参数,单位为ms

var timerId = setTimeout(function|code, delay)
setTimeout("console.log(2)",1000);

它返回定时器的编号,以后可以用来取消这个定时器。

2、使用注意

推迟执行的代码必须以字符串的形式,放入setTimeout。
因为引擎内部使用eval函数,将字符串转为代码。
如果推迟执行的是函数,则可以直接将函数名,放入setTimeout
一方面eval函数有安全顾虑,另一方面为了便于JavaScript引擎优化代码,setTimeout方法一般总是采用函数名的形式

三、setInterval()

setInterval函数的用法与setTimeout完全一致,区别仅仅在于setInterval指定某个任务每隔一段时间就执行一次。如果不取消的话,就会无限次的定时执行。
第一个参数是函数名或者语句,第二个参数是间隔执行的时间,单位为ms
例一:实现自增数据输出

var i=0
var timer=setInterval(function(){console.log(i++)},1000)
//不要在function传递i参数,不然得到的就是NaN

例二:实现定时器的功能

var timer=setInterval(function(){console.log(new Date)},1000)

四、解除定时器clearTimeout(),clearInterval()

setTimeout和setInterval函数,都返回一个表示计数器编号的整数值。
将该整数传入clearTimeout和clearInterval函数,就可以取消对应的定时器。

var id1 = setTimeout(f,1000);
var id2 = setInterval(f,1000);

clearTimeout(id1);
clearInterval(id2);

五:举个例子
其实这篇文章写定时器的经典案例写的很棒JavaScrip同步、异步、回调执行顺序之经典闭包setTimeout分析

var i=0;
for(var i=0; i<10; i++){
  setTimeout(function(){
      console.log(i)
  }, 1000)
}

执行结果:

解析:先执行主线程的for循环,for循环执行了10次,把匿名函数添加了到任务序列10次。等for循环执行完毕,i变成10之后,把任务序列的函数添加到主线程,输出10次i=10.

var t = true;  
setTimeout(function(){ 
  t = false; 
}, 1000);  

while(t){console.log("end") }  

执行结果:不停的输出end,不会再1000ms之后停止的。
解析:因为while循环是在主线程执行,主线程的while的循环不停止,是不会再执行任务队列里面setimeout的函数的。

六、单线程模型

五、六、七章的内容全部来源于 阮一峰JavaScript 标准参考教程(alpha)
单线程模型指的是,JavaScript 只在一个线程上运行。也就是说,JavaScript 同时只能执行一个任务,其他任务都必须在后面排队等待。

注意,JavaScript 只在一个线程上运行,不代表 JavaScript 引擎只有一个线程。事实上,JavaScript 引擎有多个线程,单个脚本只能在一个线程上运行(称为主线程),其他线程都是在后台配合。

七、同步任务和异步任务

五、六、七章的内容全部来源于 阮一峰JavaScript 标准参考教程(alpha)
程序里面所有的任务,可以分成两类:同步任务(synchronous)和异步任务(asynchronous)。

同步任务是那些没有被引擎挂起、在主线程上排队执行的任务。只有前一个任务执行完毕,才能执行后一个任务。

异步任务是那些被引擎放在一边,不进入主线程、而进入任务队列的任务。只有引擎认为某个异步任务可以执行了(比如 Ajax 操作从服务器得到了结果),该任务(采用回调函数的形式)才会进入主线程执行。

八、任务队列

JavaScript 运行时,除了一个正在运行的主线程,引擎还提供一个任务队列(task queue),里面是各种需要当前程序处理的异步任务。

首先,主线程会去执行所有的同步任务。等到同步任务全部执行完,就会去看任务队列里面的异步任务。如果满足条件,那么异步任务就重新进入主线程开始执行,这时它就变成同步任务了。等到执行完,下一个异步任务再进入主线程开始执行。一旦任务队列清空,程序就结束执行。

引用这一次,彻底弄懂 JavaScript 执行机制这篇文章的解析:

同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。
当指定的事情完成时,Event Table会将这个函数移入Event Queue。
主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。
上述过程会不断重复,也就是常说的Event Loop(事件循环)。

九、异步与回调函数

来源:如果没有callback函数,会先执行f2,f3函数再执行f2函数。
但是如果f1,f2函数是有先后顺序的,必须f1执行完成,再执行f2的话(f1可能是获取ajax,f2是处理ajax数据),就需要回调函数。

给f1设置callback函数做参数,然后把这个参数当成函数执行,执行f1的过程中,设置了一个定时器,等数据到来之后,再去执行callback函数。然后把f2作为f1的参数来调用

function f1(callback){
    setTimeout(function(){
        //做某件事,可能很久
        console.log("别急,开始执行f1")
        for(var i=0;i< 100000;i++){

        }
        console.log("f1执行完了")

        callback()
    }, 0);

}
function f2(){
    console.log("执行f2");
}
function f3(){
    console.log("执行f3");
}
f1(f2) //当f1执行完之后再执行 f2
f3()
10、函数节流

转载一篇函数节流与函数防抖,写的非常好,具体内容可看这篇文章。我不再赘述,我只记录一下节流的代码

 var timer
  function hiFrequency(){
      if(timer){
          clearTimeout(timer)
      }
        timer = setTimeout(function(){
             console.log("do something")
        }, 300)
  }

  hiFrequency()
  hiFrequency()
  hiFrequency()

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99318.html

相关文章

  • 笔记】 你不知道的JS读书笔记——异步

    摘要:异步请求线程在在连接后是通过浏览器新开一个线程请求将检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件,将这个回调再放入事件循环队列中。 基础:浏览器 -- 多进程,每个tab页独立一个浏览器渲染进程(浏览器内核) 每个浏览器渲染进程是多线程的,主要包括:GUI渲染线程 JS引擎线程 也称为JS内核,负责处理Javascript脚本程序。(例如V8引擎) JS引擎线程负...

    junnplus 评论0 收藏0
  • 基本方法笔记 - 收藏集 - 掘金

    摘要:探讨判断横竖屏的最佳实现前端掘金在移动端,判断横竖屏的场景并不少见,比如根据横竖屏以不同的样式来适配,抑或是提醒用户切换为竖屏以保持良好的用户体验。 探讨判断横竖屏的最佳实现 - 前端 - 掘金在移动端,判断横竖屏的场景并不少见,比如根据横竖屏以不同的样式来适配,抑或是提醒用户切换为竖屏以保持良好的用户体验。 判断横竖屏的实现方法多种多样,本文就此来探讨下目前有哪些实现方法以及其中的优...

    maochunguang 评论0 收藏0
  • 前端学习笔记(CSS、JS基础篇)

    摘要:搜索引擎中有一个爬虫模块,在页面中使用诸如等强调式的标签,有利于,说白了就是有利于被搜索到。定位相对定位不影响元素本身特性不使元素脱离文档流。定时器如果是由事件控制的,要先关再开,避免多次触发而混乱。 CSS篇 注意:css注释使用/ /,而不是或者//,否则很容易导致不明错误!!! div padding:内边距。盒子内容与盒子边框的距离设置,相当于给盒子加了厚度,使用此属性后会改...

    caikeal 评论0 收藏0
  • 前端学习笔记(CSS、JS基础篇)

    摘要:搜索引擎中有一个爬虫模块,在页面中使用诸如等强调式的标签,有利于,说白了就是有利于被搜索到。定位相对定位不影响元素本身特性不使元素脱离文档流。定时器如果是由事件控制的,要先关再开,避免多次触发而混乱。 CSS篇 注意:css注释使用/ /,而不是或者//,否则很容易导致不明错误!!! div padding:内边距。盒子内容与盒子边框的距离设置,相当于给盒子加了厚度,使用此属性后会改...

    xietao3 评论0 收藏0
  • JS性能优化笔记

    摘要:四如果需要遍历数组,应该先缓存数组长度,将数组长度放入局部变量中,避免多次查询数组长度。五尽量选用局部变量而不是全局变量。所以如果这样的表达式重复出现,只要可能,应该尽量少出现这样的表达式,可以利用局部变量,把它放入一个临时的地方进行查询。 通过网上查找资料了解关于性能优化方面的内容,现简单整理,仅供大家在优化的过程中参考使用,如有什么问题请及时提出,再做出相应的补充修改。 一、 让...

    baoxl 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<