摘要:的执行机制就是一个主线程一个任务队列。同步任务就是放在主线程上执行的任务,异步任务就是放在任务队列的任务。和上述运行的机制主要说明的是,而的出现及普及,又有了新的概念,,它的出现,进一步,中分为两种任务类型和,在中,称为,可称为。
上一篇文章主要整理了一下js引擎是如何工作的,这篇文章主要整理js的事件循环Event loop,以及异步编程的原理事件循环Event loop
之前文章中有讲到js是单线程的,而浏览器渲染内核包含多个线程的,和js代码部分相关的线程有如下几个:
js引擎线程
处理ajax请求的线程,
处理DOM事件的线程,
定时器,
读写文件的线程(Node.JS)等
因为JS是单线程的,这是从JS引擎的角度来看的,所谓的单线程就是指在JS引擎中负责解释和执行JS代码的线程只有一个:主线程。
js分为同步任务和异步任务,同步任务都在主线程上执行,就形成一个执行栈,主线程之外,事件触发线程管理着一个任务队列,只要异步任务有了运行结果,就在任务队列中放置一个事件。一旦执行栈中所有的同步任务执行完毕(此时js引擎空闲),系统就会读取任务队列,将可运行的异步任务添加到可执行栈中,开始执行。
JS的执行机制就是一个主线程 + 一个任务队列。同步任务就是放在主线程上执行的任务,异步任务就是放在任务队列的任务。所有的同步任务都在主线程执行,这构成了一个执行栈,异步任务有了运行结果会在任务队列中放置一个事件,比如定时2秒,到2秒后才能放进任务队列(callback放进任务队列,而不是setTimeout函数放进队列)。
事件循环(Event Loop)—— 脚本运行时,先依次运行执行栈,然后从队列中提取事件来运行任务队列中的任务,这个过程是不断重复的。所以叫事件循环(Event Loop)。
macrotask和microtask上述js运行的机制主要说明的是es5,而es6的出现及普及,又有了新的概念,promise,它的出现,进一步,JS中分为两种任务类型:macrotask和microtask,在ECMAScript中,microtask称为jobs,macrotask可称为task。
分别很么样的场景会形成macrotask和microtask呢?
macrotask:主代码块,setTimeout,setInterval, setImmediate, I/O, UI rendering. 等(可以看到,事件队列中的每一个事件都是一个macrotask)
microtask: process.nextTick, Promise(原生),Object.observe,MutationObserver
在node环境下,process.nextTick的优先级高于Promise,也就是可以简单理解为:在宏任务结束后会先执行微任务队列中的nextTickQueue部分,然后才会执行微任务中的Promise部分。总结下运行机制:
执行一个宏任务(栈中没有就从事件队列中获取)
执行过程中如果遇到微任务,就将它添加到微任务的任务队列中
宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)
当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染
渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)
案例说明案例1:
setImmediate(function(){ console.log(1); },0); setTimeout(function(){ console.log(2); },0); new Promise(function(resolve){ console.log(3); resolve(); console.log(4); }).then(function(){ console.log(5); }); console.log(6); process.nextTick(function(){ console.log(7); }); console.log(8);
根据js的运行原理解释上面代码的执行顺序:
第一步 script整体代码被执行,执行过程为
创建setImmediate macro-task
创建setTimeout macro-task
创建micro-task Promise.then 的回调,并执行script console.log(3); resolve(); console.log(4); 此时输出3和4,虽然resolve调用了,执行了但是整体代码还没执行完,无法进入Promise.then 流程。
console.log(6)输出6
process.nextTick 创建micro-task
console.log(8) 输出8
第一个过程过后,已经输出了3 4 6 8
第二步 由于其他micro-task 的 优先级高于macro-task。
此时micro-task 中有两个任务按照优先级process.nextTick 高于 Promise。 所以先输出7,再输出5
第三步 micro-task 任务列表已经执行完毕,家下来执行macro-task. 由于setTimeout的优先级高于setIImmediate,所以先输出2,再输出1。
参考:https://blog.csdn.net/gy_u_yg...
https://blog.csdn.net/m0_3775...
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/53508.html
摘要:的执行机制就是一个主线程一个任务队列。同步任务就是放在主线程上执行的任务,异步任务就是放在任务队列的任务。和上述运行的机制主要说明的是,而的出现及普及,又有了新的概念,,它的出现,进一步,中分为两种任务类型和,在中,称为,可称为。 上一篇文章主要整理了一下js引擎是如何工作的,这篇文章主要整理js的事件循环Event loop,以及异步编程的原理 事件循环Event loop 之前文章...
摘要:引擎的运行原理引擎也是程序,是属于浏览器的一部分,由浏览器厂商自行开发。为了提高运行速度,现代浏览器一般采用即时编译即字节码只在运行时编译,用到哪一行就编译哪一行,并且把编译结果缓存这样整个程序的运行速度能得到显著提升。 相信大家在面试的过程中经常遇到查看执行顺序的问题,如setTimeout,promise,async await等等,各种组合,是不是感觉头都要晕掉了,其实这些问题最...
摘要:引擎的运行原理引擎也是程序,是属于浏览器的一部分,由浏览器厂商自行开发。为了提高运行速度,现代浏览器一般采用即时编译即字节码只在运行时编译,用到哪一行就编译哪一行,并且把编译结果缓存这样整个程序的运行速度能得到显著提升。 相信大家在面试的过程中经常遇到查看执行顺序的问题,如setTimeout,promise,async await等等,各种组合,是不是感觉头都要晕掉了,其实这些问题最...
阅读 3402·2021-11-24 09:38
阅读 3188·2021-11-22 09:34
阅读 2097·2021-09-22 16:03
阅读 2349·2019-08-29 18:37
阅读 369·2019-08-29 16:15
阅读 1760·2019-08-26 13:56
阅读 852·2019-08-26 12:21
阅读 2196·2019-08-26 12:15