JavaScript执行机制
js单线程
单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。
于是,所有任务可以分成两种:同步任务(synchronous) 异步任务(asynchronous)
同步任务指的是:在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务。
异步任务指的是:不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。(主线程会监听任务队列)
微任务MicroTask引入
对于每个宏任务而言,起内部都有一个微任务队列,为什么要引入微任务?微任务在时候执行?
1.将异步回调进行宏任务队列的入队操作
2.将异步回调放到当前宏任务的末尾
如果采用第一种方式,那么执行回调的实际应该是在前面所有的宏任务完成之后,倘若现在的任务队列非常长,那么回调迟迟得不到执行,造成应用卡顿
为了避免这样的问题,V8引入了第二种方式,这就是微任务的解决方式。在每一个宏任务中定义一个微任务队列,当该宏任务执行完成,会检查其中的微任务队列,如果为空则直接
执行下一个宏任务,如果不为空,则依次执行微任务,执行完成才去执行下一个宏任务
常见的微任务有MutaitionObserver Promise.then或reject 以及Promise为基础开发的其他技术 比如fetch API,还包括V8垃圾回收过程
Event Loop概念:主线程从"任务队列"中读取事件,这个过程是循环不断的,所以整个的这种运行机制称为Event Loop(事件循环)
console.log('1'); setTimeout(function() { console.log('2'); process.nextTick(function() { console.log('3'); }) new Promise(function(resolve) { console.log('4'); resolve(); }).then(function() { console.log('5') }) }) process.nextTick(function() { console.log('6'); }) new Promise(function(resolve) { console.log('7'); resolve(); }).then(function() { console.log('8') }) setTimeout(function() { console.log('9'); process.nextTick(function() { console.log('10'); }) new Promise(function(resolve) { console.log('11'); resolve(); }).then(function() { console.log('12') }) })