type
status
date
slug
summary
tags
category
icon
password
同步和异步
JS 中所有任务可以分为 2 种,一种是同步任务(synchronous),一种是异步任务(asynchronous)
同步任务:在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务。是由 js 执行栈/回调栈执行的
异步任务:不进入主线程、而进入任务队列的任务,当主线程中的任务运行完成了,才会从任务队列中取出异步任务,放入主线程中执行
而异步任务,又可以分为宏任务和微任务
宏任务
宏任务是由宿主环境发起的,比如浏览器、Node等,宏任务的异步代码有:
- script(整体代码块)
- setTimeout / setInterval 定时器
- setImmediate 定时器
- UI交互事件
- postMessage
- ......等等
微任务
微任务是由JS引擎发起的,微任务的异步代码有:
- process.nextTick (Node.js环境)
- Promise.then()/catch()/finally() 。注意,
Promise
本身同步,只是它里面的then/catch
的回调函数是异步的微任务
- Async/Await
- Object.observe
- ......等等
任务的执行顺序
有人说宏任务先于微任务执行,也有人说微任务先于宏任务执行
其实,由于整个
script
身就是一个大的宏任务,所以在执行任务时,肯定是执行script
这个大的宏任务里面的代码,因此,我们也可以说是宏任务优先于微任务但是如果我们忽略
script
这个大的宏任务,仅仅只讨论script
里包含的任务代码块,那么任务的执行顺序就一定是微任务优先于宏任务在这里,我们就先忽略
script
,执行顺序就为:同步任务 ---> 微任务 ---> 宏任务案例演示:下面代码的执行结果是什么?
我们可以通过文章开头的理论解释,将上面代码分为同步任务、微任务、宏任务三块,
哪些代码属于同步任务,哪些代码属于微任务,哪些代码属于宏任务,如下图所示:
将我们分析好的代码,分开放在相应的队列里,可得到以下代码执行的流程图示:
所以这个案例,最终得到的执行结果就是:
1 3 4 5 “success” 2
小试牛刀
请说一说以下代码的执行顺序和结果:
解答:
- 作者:衔蝉
- 链接:https://xianchan.ah.cn/article/MacroTask-MicroTask
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。