javascript每句代码背后的故事五

原创 天下无双 随笔 原生javascript 111阅读 2019-02-26 19:18:48 举报

常规来说js是单线程的,我们写的代码应该都是一步一步往下走的,但是js是放在客户端执行的,如果仅仅是这样,那很多时候我们页面会卡住,所以js里就有很多能打破这种执行方式的方法,比如setTimeout,setInterval,Promise.then catch finally。node里面还有setImmediate,process.nextTick,I/O操作。es6又新增了requestAnimationFrame,当这些方法和我们正常执行的代码或者这些代码互相包含的时候,谁先执行,谁后执行就是一个让人很头大的问题比如这种代码

如果我们清楚这些方法的一些背后知识,那就会很清晰了。

要理解它背后的知识,借助我前面说的函数执行栈来理解就会稍微容易一些,前面我说过,js里面需要执行的函数都是用栈来管理的,但是上面我们说的那些方法他们一开始是不入执行栈的,而是跑到各自对应的宏任务队列和微任务队列去,如果有上面那些方法时候js引擎处理的方式是这样的:先让正常的同步任务入栈执行,然后发现一个有定时器的宏任务,先不管它,继续往下走发现一个有回调的微任务,把这个微任务扔进微任务队列里去,此时宏任务的定时器到了,然后把宏任务扔到宏任务队列里去,继续往下走发现正常的同步任务已经都执行完了,这时去微任务队列里把里面的所有微任务都推到栈里执行,执行完后去宏任务队列里去依次把宏任务推到执行栈里执行。按照这个思路,理解一下上面的代码

console.log(1)是正常的同步任务直接执行,往下走碰到setTimeout这个是有定时器的宏任务,但是时间是0直接扔到宏任务队列里去,继续走碰到Promise这个是正常同步任务直接执行,继续往下走碰到Promise.then这个是微任务放到微任务队列里去,继续往下走又碰到一个setTimeout是个宏任务放进宏任务队列里去,再往下发现正常的同步任务都执行完了,到微任务队列里把Promise.then拿出来执行,微任务执行完后再去宏任务队列依次把setTimeout里的回调执行。最后打印结果就是1,3,4,2,5。

按照上面说的思路来分析这种代码,不管怎么嵌套,我们都能准确的分析出代码执行顺序,我们只需要知道哪些是宏任务,哪些是微任务。

宏任务:js里面的setTimeout,setInterval,requestAnimationFrame,node里面还有setImmediate,I/O

微任务:js里面的Promise.then catch finally,node里面的process.nextTick

上面一直说执行微任务,执行宏任务等等,具体什么时候执行宏任务,什么时候执行微任务是有一个机制不断的轮询的,这个机制就是Event Loop,具体这个机制怎么运行的,没深入研究过。

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复