JavaScript事件循环机制
javaScript是单线程的语言:
众所周知,javaScript是一门单线程语言;何为单线程?我的理解是:同一时间只能做同一件事;单线程在程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行。
白话解释:
假如去某银行办理业务,某银行的单次业务接待总量为100个客户,但此时在该银行等待办理业务的人数为150人,所以有50人是需要等待的,等待时间是未知;银行采取叫号方式进行排队办理业务,前100个人是可以完成业务办理的,此时这100个人形成了一个排队的队列,在计算机中我们称之为线程;只有线程队列中完成了任务或者空闲,剩下的50人才能继续办理业务;
javaScript为什么会是单线程的语言?
在《javaScript高级程序设计》一书中有一个很好的解释:如果JS是多线程语言,那么假如当多个线程同时操作同一个DOM的时候,浏览器该如何渲染?浏览器该听哪个线程的指令?渲染结果是否会超出预期?基于这个特性,JS必须只能是单线程语言;
进程与线程的区别:
进程:是cpu资源分配的最小单位;(能拥有独立资源和独立运行的最小单位)
线程:是cpu资源调度的最小单位;(线程是建立在进程基础上一次程序最小的执行单位,一个进程中可以有多个线程)
resolve、.then、.catch等方法
才是异步任务)、process.nextTick
解析图文:
同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table(任务队列)并注册函数。
当指定的事情完成时,Event Table(任务队列)会将这个函数移入Event Queue(事件队列)。
主线程内的任务执行完毕为空,会去Event Queue(事件队列)读取对应的函数,进入主线程执行。
上述过程会不断重复循环,也就是常说的Event Loop(事件循环)。
举个例子:
console.log('script start');
setTimeout(function() { console.log('setTimeout'); }, 0); Promise.resolve().then(function() { console.log('promise1'); }).then(function() { console.log('promise2'); }); console.log('script end');
输出结果应为:
script start
script end
promise1
promise2
setTimeout
执行过程解析:
首先循环浏览器会执行第一步的同步任务,当执行到setTimeout的时候发现是异步的宏任务然后放入到任务队列中,接着往下执行Promise.then,发现Promise.then也是异步任务且是微任务,继续放入到队列中接着往下走执行"sciprt end " ;执行完"script end "之后发现主进程的同步任务都执行完了,然后开始执行异步任务,异步任务任务又分为宏任务和微任务,我们前面说过微任务会优先于宏任务执行;所以我们继续执行" promise1 ",然后往下走发现还有个.then的微任务没有执行,接着往下执行" promise2 ",至此所有的微任务执行完毕我们再去执行宏任务" setTimeout ",所以最终的执行结果应该为:script start > script end > promise1 > promise2 > setTimeout
什么?学会了?上面demo太简单?那我们再看一下复杂一丢丢的例子来检验一下我们的学习成果
console.log('1'); setTimeout(() => { console.log('2') }, 1000); new Promise((resolve, reject) => { setTimeout(() => { console.log('3'); }, 0); console.log('4'); resolve(); console.log('5'); }).then(() => { console.log('6'); }); console.log('7');
这个例子是在上面例子的基础上加以改造进行了嵌套