定时器

JavaScript提供定时执行代码的功能,叫做定时器(timer),主要由setTimeout()setInterval()这两个函数来完成。

setTimeout()

setTimeout()函数用来指定某个函数或某段代码,在多少毫秒之后执行。它返回一个整数,表示定时器编号,这个定时器可以被取消。

var timerId = setTimeout(func|code, dely)
//参数func|code是将要推迟执行的函数名或一段代码,参数delay是推迟的毫秒数。



注:返回的第一个整数为为定时器编号

setInterval()

setInterval函数的用法与setTimeout完全一致,区别仅仅在于setInterval指定某个任务每隔一段时间就执行一次,也就是无限次的定时执行。


clearTimerout(),clearInterval()

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


单线程模型

单线程模型指的是,JavaScript只在一个线程上运行。也就是说,JavaScript同时只能执行一个任务,其他任务都必须在后面排队等待。
注:JavaScript只在一个线程上运行,不代表JavaScript引擎只有一个线程。事实上,JavaScript引擎有多个线程,单个脚本只能在一个线程上运行,其他线程都是在后台配合

  • JavaScript运行时,除了一个运行线程,引擎还提供一个消息列队(message queue),里面是各种需要当前程序处理的消息。新的消息进入队列的时候会排在队列尾端。
  • 运行线程只要发现消息列队不为空,就会去除排在第一位的那个消息,执行它对应的回调函数。等到执行完,再取出排在第二位的消息,不断循环,知道消息队列变空为止。
  • 每条消息与一个回调函数相联系,也就是说,程序只要收到这条消息,就会执行对应的函数。另一方面,进入消息队列的消息,必须有对应的回掉函数。
  • 另一种情况是setTimeout会在指定时间向消息队列添加一条消息。如果消息队列之中,此时没有其他消息,这条消息会立即得到处理;否则这条消息不得不等到其他消息处理完,才会的到处理。因此,setTimeout指定的执行时间,只是一个最早可能发生的时间,并不能保证一定会在那个时间发生。
  • 一旦当前执行栈空了,消息队列就会取出排在第一位的那条消息,传入程序。程序开始执行对应的回掉函数,等到执行完,仔处理下一条下消息。

运行机制

setTimeout和setInterval的运行机制是,将制定的代码移除本次执行,等到下一轮Event Loop时,在检查是否到了指定时间。如果到了,就执行对应的代码;如果不到,就等到下一轮Event Loop时重新判断。这意味着,setTimeout指定的代码,必须等到本次执行的所有代码都执行完,才会执行。
setTimeout的作用是将代码推迟到指定时间执行,如果指定时间为0,即setTimeout(f,0),那么不会立刻执行



setTimeout(f,0)将第二个参数设为0,作用是让f在现有的任务(脚本的同步任务和“任务队列”中已有的事件)一结束就立刻执行。也就是说,setTimeout(f,0)的作用是,尽可能早地执行指定的任务。



在看一个例子:
var t = true;  
setTimeout(function(){ 
  t = false; 
}, 1000);  

while(t){ }  
console.log('end')
//结果是无限循环

因为setTimeout会被放在任务队列中,然后执行while,因为 t= true,
所以一直执行while(t){},不会执行console.log('end')

异步与回调

常见的JavaScript任务:

  • 执行JavaScript代码
  • 对用户的输入(包括鼠标点击、键盘输入等等)做出反应
  • 处理异步的网络请求

异步任务:不进入JavaScript执行进程,而进入“任务队列”(task queue)的任务,只有“任务队列”通知主进程,某个异步任务可以执行了,该任务(采用回调函数的形式)才会进入JavaScript进程执行。
以Ajax操作为例,它可以当作同步任务处理,也可以当作异步任务处理,由开发者决定。如果是同步任务,主线程就等着Ajax操作返回结果,再往下执行;如果是异步任务,该任务进入“任务队列”,JavaScript进程跳过Ajax操作,直接往下执行,等到Ajax操作有了结果,JavaScript进程再执行对应的回调函数。
让我们看个例子:



使用回调函数:


函数节流

如果一个函数短时间内执行很多次,会以最后一次为准。例如百度搜索框,当我们输入字符会有相应的检索结果出现



在我们输入的这个过程,用户还没有完成输入,但会不断有新的检索结果出现,而搜索结果始终以最后一次为准,所以,这个过程一定程度的浪费了资源



使用setTimeout实现函数节流

改造:


你可能感兴趣的:(定时器)