前端的那些事--定时器的异步过程

话不多说题目入手:

setTimeout(function(){
	console.log(1);
},0)
console.log(2);

上面这一道题目测试两个语句的输出顺序,有基础的同学估计很快就得出答案,2 1,那么入门的同学就好奇了,js不是按顺序一步一步执行吗,这里就且罢听我道说。

浏览器的工作原理
名称作用
进程cpu资源分配的最小单位
线程cpu调度的最小单位

就是说,进程包括线程,一个进程包含多个线程,浏览器是多进程:

进程名称作用
Browser进程浏览器的主线程,主要负责浏览器的页面,功能包括书签、前进后退、资源下载管理等
渲染进程内核进程、负责页面渲染、JS执行,一个浏览器可以包含多个渲染进程
GPU进程负责GPU渲染,整个浏览器应用程序只有一个
插件进程每个插件对应一个进程

在渲染引擎中又包括:

渲染引擎中的线程作用
GUI线程解析HTML、CSS和渲染页面
JS引擎线程js内核,解析和执行JS代码
事件线程控制事件循环
定时器线程处理定时器相关逻辑
异步请求线程发起Ajax时会生成该线程

这里可以看到定时器是有单独的线程,有专门的执行它的地方,而这个地方是个异步执行环境,js引擎执行是一个同步的过程,同步和异步不过多阐述,前面文章有讲:js时间线以及异步,异步执行环境就不得不提一下事件队列

任务队列

当js引擎开始解析代码时,把任务压入执行栈,然后判断栈中任务类型,异步就把任务丢到异步处理模块中,有结果时把回调函数放到任务队列中,可以理解成分类,把各自放到对应类型的执行环境,执行栈秉承先进后出的顺序,任务队列则是先进先出,执行栈先执行任务,当执行栈清空会把任务队列中的任务拉到执行栈执行,而执行栈执行任务队列中任务的过程又叫做事件循环

事件循环

在这里插入图片描述

宏任务和微任务

读取任务队列中的任务不是说优先级一样,这里就诞生了宏任务和微任务的概念

任务代表
宏任务script环境 setTimeout、setInterval、I/O、postMessage、 MessageChannel、setImmediate
微任务Promise,process.nextTick,MutaionObserver

任务队列进入执行栈中会以优先级高的先入栈,这里注意一点,script整体环境都是一个宏任务,所以微任务由宏任务执行过程中产生,除去同步代码执行完毕后,微任务执行优先级总是要优于剩余的异步宏任务。
在这里插入图片描述

总结

综合上诉,那么开头那个题就相当简单不过了,先入栈,然后定时器丢到任务队列,任务栈只剩log(2),出栈读取任务队列log(1),清空栈输出,再来一个综合性的题目恢复一下

setTimeout(function(){
	console.log(1)
},1)
new Promise((res,rej) => {
	console.log(2);
	res("ok")
}).then(() => {
	console.log(3)
})
console.log(4)

输出的顺序那就应该是2431了,别看promse是异步处理,但是new promise()是同步,只有then回调才是异步,所以同步顺序中先输出24,任务栈中读取promise优先级大于settimeout,输出31

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值