前言
计时器setTimeout和setInterval是我们经常会用到的,它用于在指定的毫秒数后调用函数或计算表达式。
一、setTimeout的语法:
setTimeout(cb, time);
setTimeout传入的是两个参数,第一个参数是cb代表的是回调函数callback,第二个代表的是时间,以ms计算。
作用:setTimeout的含义是定时器,到达一定的时间触发一次
1.1、setTimeout原理
首先看一段代码:
demo1.png
在上面的代码中,定义了一个setTimeout定时器,延时时间是500毫秒。
你是不是觉得打印结果是: 500
但是浏览器的内核是多线程的,多个线程在内核的相互配合下保持同步:
- JavaScript引擎是基于事件驱动单线程执行的,JavaScript引擎一直等待着任务队列中任务的到来,然后加以处理,浏览器无论什么时候都只有一个JavaScript线程在运行JavaScript程序。
- GUI渲染线程负责渲染浏览器界面,当界面需要重绘(Repaint)或由于某种操作引发回流(Reflow)时,该线程就会执行。但需要注意,GUI渲染线程与JavaScript引擎是互斥的,当JavaScript引擎执行时GUI线程会被挂起,GUI更新会被保存在一个队列中等到JavaScript引擎空闲时立即被执行。
- 事件触发线程,当一个事件被触发时,该线程会把事件添加到待处理队列的队尾,等待JavaScript引擎的处理。这些事件可来自JavaScript引擎当前执行的代码块如setTimeout、也可来自浏览器内核的其他线程如鼠标点击、Ajax异步请求等,但由于JavaScript的单线程关系,所有这些事件都得排队等待JavaScript引擎处理(当线程中没有执行任何同步代码的前提下才会执行异步代码)。
我们回顾刚刚的代码: demo1.png 虽然setTimeout的延时时间是500毫秒,可是由于while循环的存在,只有当间隔时间大于1000毫秒时,才会跳出while循环,也就是说,在1000毫秒之前,while循环都在占据着JavaScript线程。也就是说,只有等待跳出 while后,线程才会空闲下来,才会去执行之前定义的setTimeout。最后,我们可以总结出,setTimeout只能保证在指定的时间后将任务(需要执行的函数)插入任务队列中等候,但是不保证这个任务在什么时候执行。
二、setInterval的语法:
setInterval(cb, time);
setInterval传入的也是两个参数,第一个参数是cb代表的是回调函数callback,第二个代表的也是时间,以ms计算。
作用:setInterval含义是计时器,到达一定时间触发一次,并且会持续触发。
网友评论