宏任务和微任务详解
前言:这个真的很重要,开发的时候利用好宏任务和微任务的特性,能够把帮助我们在执行业务函数的时候设定一定的顺序
JavaScript的单线程和任务队列
- Js的内部引擎是单线程的,但是浏览器它是多线程的,单线程一意味着所有任务需要排队,前一个任务结束,才会执行后一个任务。
- 如果前一个任务耗时很长,后一个任务就不得不一直等待。而且有些时候,有些任务会挂载于等待状态,这个时候其实可以先去运行别的任务,等上一个任务需要再启动的时候,再来运行它。
- 于是,为了解决这个问题,有了同步任务(synchronous)和异步任务(asynchronous)。
- 同步任务指的是,在主线程上,排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务
- 异步任务指的是,不进入主线程,而进入“任务队列”(task queue)的任务,只有“任务队列”通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
这里借用一张图,就很好解释了同步和异步任务的执行过程
宏任务和微任务
前面我们已经介绍了同步任务和异步任务的执行过程,为了协调这些任务有条不紊地在主线程上执行,页面进程引入了消息队列和事件循环机制。
宏任务(task):就是JS 内部(任务队列里)的任务,严格按照时间顺序压栈和执行。比如 script(整体代码)、 setTimeOut、setInverter、setImmediate 、 MessageChannel等。
微任务(Microtask ):微任务就是一个需要异步执行的函数,执行时机是在主函数执行结束之后、宏任务结束之前。比如process.nextTick、Promise.then()、async/await(实际就是Promise)、MutationObserver(HTML5新特性)
主要的执行顺序是:
运行机制
- 在执行栈中执行一个宏任务。
- 执行过程中遇到微任务,将微任务添加到微任务队列中。
- 当前宏任务执行完毕,立即执行微任务队列中的任务。
- 当前微任务队列中的任务执行完毕,检查渲染,GUI线程接管渲染。
- 渲染完毕后,js线程接管,开启下一次事件循环,执行下一次宏任务(事件队列中取)。
借用一下别人的例子:
1 | console.log('---start---');//第一轮主线程 |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 AliveSeven's Blog!
评论