写这一篇的时候,西瓜君查阅了很多资料和文章,但是相当多的文章写的都很简单,甚至互相之间有矛盾,这让我很困扰;同时也让我坚定了要写出一篇好的关于JS异步、单线程、事件循环的文章,下面,让我们一起来学习本文吧,冲鸭~~
### 1. 什么是单线程
//栗子1
console.log(1)
console.log(2)
console.log(3)
//输出顺序 1 2 3
单线程即同一时间只做一件事
为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。
同步任务:在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务
异步:不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行
//异步的栗子
console.log(1)
setTimeout(()=>{
console.log(2)
},100)
console.log(3)
//输出顺序 1 3 2
如果在JS代码执行过程中,某段代码执行过久,后面的代码迟迟不能执行,产生阻塞(即卡死),会影响用户体验。
JS 实现异步时通过 事件循环(Event Loop),下面我们来了解一下
先理解几个概念
当一个JS文件第一次执行的时候,js引擎会 解析这段代码,并将其中的同步代码 按照执行顺序加入执行栈中,然后从头开始执行。如果当前执行的是一个方法,那么js会向执行栈中添加这个方法的执行环境,然后进入这个执行环境继续执行其中的代码。当这个执行环境中的代码 执行完毕并返回结果后,js会退出这个执行环境并把这个执行环境销毁,回到上一个方法的执行环境。这个过程反复进行,直到执行栈中的代码全部执行完毕。
举个栗子:
//Event loop
//(1)
console.log(1)
//(2)
setTimeout(()=>{
console.log(2)
},100)
//(3)
console.log(3)
所以结果是 1 3 2
注:setTimeout/Promise等我们称之为任务源。而进入任务队列的是他们指定的回调
上面的循环只是一个宏观的表述,实际上异步任务之间也是有不同的,分为 宏任务(macro task) 与 微任务(micro task),最新的标准中,他们被称为 task与 jobs
下面我们再详细讲解一下执行过程
执行栈在执行的时候,会把宏任务放在一个宏任务的任务队列,把微任务放在一个微任务的任务队列,在当前执行栈为空的时候,主线程会 查看微任务队列是否有事件存在。如果微任务队列不存在,那么会去宏任务队列中 取出一个任务 加入当前执行栈;如果微任务队列存在,则会依次执行微任务队列中的所有任务,直到微任务队列为空(同样,是吧队列中的事件加到执行栈执行),然后去宏任务队列中取出最前面的一个事件加入当前执行栈...如此反复,进入循环。
注:
举个栗子:
//Event loop
//(1)
setTimeout(()=>{
console.log(1)
},100)
//(2)
setTimeout(()=>{
console.log(2)
},100)
//(3)
new Promise(function(resolve,reject){
//(4)
console.log(3)
resolve(4)
}).then(function(val){
//(5)
console.log(val);
})
//(6)
new Promise(function(resolve,reject){
//(7)
console.log(5)
resolve(6)
}).then(function(val){
//(8)
console.log(val);
})
//(9)
console.log(7)
//(10)
setTimeout(()=>{
console.log(8)
},50)
*上面的代码在node和chrome环境的正确打印顺序是 3 5 7 4 6 8 1 2
下面分析一下执行过程:
注:因为渲染也是宏任务,需要在一次执行栈执行完后才会执行渲染,所以如果执行栈中同时有几个同步的改变同一个样式的代码,在渲染时只会渲染最后一个
写到这里,仍然觉得还有很多知识点没有写出来,但是想写又不知道从哪里入手。于是决定今天就写到这里,日后再做补充。
到这篇,JS三座大山系列就暂时完结了,在这其中自己也学到了很多,希望能继续输出一些有意义的东西,加油,西瓜君~~
参考文章:
https://www.jianshu.com/p/12b9f73c5a4f
https://www.cnblogs.com/cangqinglang/p/8967268.html
如有错误,请斧正
以上
原文:https://www.cnblogs.com/bloglixin/p/11959219.html