用故事解析setTimeout和setInterval(内含js单线程和任务队列)

区别:

setTimeout(fn,t):

延迟调用,超过了时间就调用回调函数,返回一个id,使用clearTimeout(id)取消执行。
注意:取消了里面的回调函数就不执行了哦,而不是取消的时候就立即执行,下面有源码可以自己cv试一下。

setInterval(fn,t):

循环调用,有周期性的调用回调函数,返回一个id,使用clearInterval(id)取消执行。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
<script>
console.log('333333333333333333333')
var aa =setTimeout(()=>{console.log("11111111111111")
},6000)
setTimeout(()=>{clearTimeout(aa)console.log("2222222222")
},3000)
</script>
</head>
<body></body>
</html>

在学习这两种延迟函数之前要最好是先了解一下JS单线程和任务队列;

举个栗子:

在广场上,只有一家一点点奶茶店(cpu),然后我(一个任务)要去买奶茶(执行这个任务),只能排一条队(js的单线程机制),虽说排队(主线程)的人很多,但是一点点工作人员工作速度确实很快,一般的人付完现金就完了(synchronous同步任务)。

但是到了我的时候,我想用支付宝支付,但是打开支付宝需要网络,需要等待支付宝软件打开(asynchronous异步任务,等待IO设备返回结果),但是为了不影响队列后面的排队者的速度,所以一点点的工作人员让我去旁边的队列里(任务队列)去等待,这个队列里面有加我一起有三个人在启动支付宝,我排在第三。

然后一段时间过后,我的和第一个人支付宝打开了(IO设备返回结果了),第二个人没打开,我和第一个人就把二维码展示出来(在任务队列中添加一个事件,表示相关异步任务可以进入主线程执行了),但是这个时候主队列里面还有一些人在买奶茶,所以,现在工作人员顾不上我。

然后我们就只能一直等待,直到主队列里面买奶茶的人都走光了,这个时候工作人员就把我和第一个人加入主队列中,然后我和第一个人就相继都买到奶茶了,主队列又没有人了,于是工作人员又去问第二个人二维码有没有出来,(这个过程叫Event Loop(事件循环)),至此基本的单线程和任务队列就完了,下面再了解一下定时器的特殊原理。

setTimeout(fn,t)

同样的,又是我(setTimeout(fn,20)函数)去买奶茶,我首先还是去排队,到我的时候我说我现在不想买,我要等到20(设置的时长)毫秒之后再买,工作人员就说,好,那你去任务队列里面去等20毫秒吧,然后我就屁颠屁颠的去了。

20毫秒后,还是老样子,工作人员要等到主队列里面人都走完了再把我拉到主队列里面去,所以我实际等待的时间=我设置的时间+设置时间到了之后主队列里面执行的时间,但是庆幸的是工作人员工作速度非常快,所以一般主队列里面是没有人的。

注意:
1、所以即使你设置超时时间为0,工作人员也不会立马执行你哦,还是会把你加到任务队列中的,谁叫你是asynchronous(异步任务)
2、你设置超时时间有用吗?实际上是没有生效的,因为html5标准规定了setTimeout设置超时时间最小值是4毫秒,如果低于这个值就会自动增加,老版本浏览器更将是把最短时间设为10毫秒,而最要命的是,如果涉及到DOM的变动的都是16毫秒一次。

setInterval(fu,t)

同样的,鸣人(setInterval(fn,1000)函数)去买奶茶,首先还是去排队,到鸣人的时候,它不仅要在1秒钟之后买,还要影分身出很多鸣人相继在1、2、3、4...之后买,工作人员同样要他和他的影分身在任务队列后面排队等会,正常情况下,主队列没人了,鸣人和他的影分身们也会在规定的时间里面相继执行。

那么问题来了

假如每个鸣人都很喜欢逼逼叨叨,那么就会发生这样子的情况:

当一秒钟后第一个鸣人从任务队列中到主队列中的时候,就一直跟工作人员逼逼叨叨(发生阻塞了,例如遇到循环不完的for),直到第四秒钟才说完(也就是b了3秒钟),这个时候第二个鸣人已经超过预定时间的两秒钟了,然后等到第二个鸣人和工作人员聊得时候又逼逼叨叨不停,又要b3秒钟,所以第二个鸣人会在第7秒b完,同理,第三个和第四个分别在第10秒和第13秒b完。

鸣人逼逼叨叨的过程如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>uaoie.top</title>
<script>
console.log('333333333333333333333')
var y=0;
var x = new Date().getTime();
var d=setInterval(a,1000);
function a() {y++;sleep(3000);if(y>=4){clearInterval(d)}
console.log(new Date().getTime()-x);
}
function sleep(sleepTime){var start=new Date().getTime();while(true){if(new Date().getTime()-start>sleepTime){break;    }}
}
</script>
</head>
<body>
</body>
</html>

导致的情况如下:

全剧终

八、彩蛋

现在我们可以很轻松的分析一下下面代码的原理(虽然我们都知道结果):

var aa=new Date().getTime()
for (var i = 0; i < 4; i++) {setTimeout(function() {console.log(new Date().getTime() -aa, i);}, 1000);
}
console.log(new Date().getTime() -aa, i);

先执行第一行,完了后执行for,循环4次也就是执行4次setTimeout函数,这个4个函数同时放在任务队列中。
然后再执行最下面的config,所以会先打印0秒和4。
然后等到一秒后,setTimeout函数从任务队列中出来到主队列,输出的是1秒和4。
所以效果如下:

posted on 2019-09-03 14:51 买辣椒也用券 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/Juaoie/p/11446302.html

用故事解析setTimeout和setInterval(内含js单线程和任务队列)相关推荐

  1. js中setTimeout的用法和JS计时器setTimeout与setInterval方法的区别和confirm方法

    setTimeout()在js类中的使用方法 setTimeout (表达式,延时时间) setTimeout(表达式,交互时间) 延时时间/交互时间是以豪秒为单位的(1000ms=1s) setTi ...

  2. 深入浅出JS定时器:从setTimeout到setInterval

    前言 当谈到 JavaScript 编程语言最基本的概念时,定时器就是一个必须掌握的知识点.在编写网站时,你经常会遇到需要在一定时间间隔内执行一些代码的情况.这时候,JavaScript 定时器就可以 ...

  3. js基础之setTimeout与setInterval原理分析

    setTimeout与setInterval概述 setTimeout与setInterval是JavaScript引擎提供的两个定时器方法,分别用于函数的延时执行和循环调用.前者的主要思想是通过一个 ...

  4. JS实现动画之setTimeout、setInterval和requestAnimationFrame

    参考:<JS高级程序设计>,这篇requestAnimationFrame文章 JS实现动画主要有三种方式:setTimeout.setInterval 和 requestAnimatio ...

  5. js的事件循环机制:同步与异步任务(setTimeout,setInterval)宏任务,微任务(Promise,process.nextTick)...

    javascript是单线程,一切javascript版的"多线程"都是用单线程模拟出来的,通过事件循环(event loop)实现的异步. javascript事件循环 事件循环 ...

  6. js setTimeout和setInterval区别

    1.区别 2.示例代码 <!DOCTYPE html> <html lang="zh"> <head> <meta charset=&qu ...

  7. js 定时器用法详解——setTimeout()、setInterval()、clearTimeout()、clearInterval()

    写在前面: 在js应用中,定时器的作用就是可以设定当到达一个时间来执行一个函数,或者每隔几秒重复执行某段函数.这里面涉及到了三个函数方法:setInterval().setTimeout().clea ...

  8. js 中 的时间类和 setTimeout 和setInterval

    首先贴代码 <!DOCTYPE html> <html><head><meta charset="UTF-8"><title& ...

  9. JS setTimeout和setInterval的区别

    1.setTimeout和setInterval都属于JS中的定时器,可以规定延迟时间再执行某个操作,不同的是setTimeout在规定时间后执行完某个操作就停止了,而setInterval则可以一直 ...

最新文章

  1. php+下载+网路错误,下载zip文件“网络错误失败”(PHP / NGINX)
  2. 十一、springboot WebMvcConfigurer与HandlerInterceptorAdapter使用
  3. 主流Java报表工具的比较
  4. pythreejs is needed for plotting with pythreejs backend
  5. 利用who,w,ps和top等指令查看linux下的进程执行情况.,UNIXLINUX操作系统实验指导书...
  6. 理解 K8s 资源更新机制,从一个 OpenKruise 用户疑问开始
  7. JAVA定义一个多边形类_如何在每个数据类别中绘制多个多边形?
  8. 统计list里面相同元素个数_LeetCode 第 347 号问题:前 K 个高频元素
  9. SAP中的时间表达方式
  10. [HTML] 关于DIV被Flash或表单遮盖的解决方法
  11. POJ 2392 Space Elevator(多重背包变形)
  12. ArcGIS 10.3 AddIN编译旧版本项目问题
  13. aspf ftp_【解析】文件传输协议:FTP、TFTP、SFTP有什么区别?
  14. 全国各省份简称、省会、经纬度
  15. 【深入理解Java原理】Java类加载机制
  16. 【WLAN】【软件】MTK芯片方案用户态和内核态通讯方式小结
  17. html里面<i>和<em>标签的区别
  18. 高级语言编译的六个过程,解释程序和编译程序的区别
  19. flutter中App签名
  20. Android 使用Service 实现的简易音乐播放器(有播放、暂停(继续)、重播、停止)

热门文章

  1. 输入一个字符,小写字母转大写,大写字母转小写,数字则输出为自身
  2. 搬:五大车载操作(VOS)系统优劣对比,车载系统架构分析
  3. 16年,悲痛又收获的一年
  4. 探索Java中empty()与isEmpty()的区别
  5. 番茄炖牛腩做法,味美汤浓开胃爽口,牛腩入口即化,太下饭!
  6. 告别平淡(平庸)从做难事儿开始
  7. 牛客网 A-吐泡泡 栈的模拟
  8. python与金融工程的区别_科研进阶 | 纽约大学 | 金融工程、量化金融、商业分析:Python金融工程分析...
  9. Android程序员生活就是这么朴实无华,那真是穷的喝自来水
  10. 【笔记】lua - 协程