1. 什么是任务?
众所周知, JavaScript是单线程的; 一个任务就是一个线程(ajax请求, 用户触发的事件都可以称之为任务), 但是不是每一个任务都是按顺序执行的,
如: 定时器, 网络延迟请求就不会顺序执行.
那么当浏览器遇到了定时器和网络延迟请求这样的任务的时候, 一直去等待它们执行完毕的话. 可能会导致页面的崩溃.
那么这是就出现了同步任务和异步任务.
2. 什么是同步任务?
立即执行的任务,在主线程上排队执行,前一个任务执行完毕,才能执行后一个任务.
简答的来说就是代码的书写顺序, 和它的执行顺序是一致的; 那么就是同步任务.
3. 什么是异步任务?
异步执行的任务,不进入主线程, 而是在异步任务有了结果后,将注册的回调函数放入任务队列中等待主线程空闲的时候读取执行.
比如: ajax, setTimeout, setInterval, Promise.then和事件回调等等.
注意: 浏览器并不是遇到了异步任务就把其放入任务队列里面, 而是触发了才会把回调函数放入任务队列等待主线程读取.
在异步任务中又细分为微任务(MacroTask)和宏任务(MicroTask).
4. 为什么有同步和异步任务之分?
可以想一想, 如果所有的任务都是同步的任务; 那我发送一个ajax请求数据, 要是网速很慢, 下面的加载就都做不了. 只能够死等着服务器响应结束, 后面的代码才会去执行; 那么页面就很乱了.
5. 什么是微任务(Macro Task)?
一般由ECMA规定的东西就是微任务, 如: promise.then/.catch/.finally.
6. 什么是宏任务(MicroTask)?
由宿主环境规定的一般都是宏任务, 如: 定时器, ajax, 事件回调, script标签.
7. 为什么需要分微任务和宏任务?
因为任务队列有一个"先进先出"的数据结构, 排在前面的事件会被主线程优先的读取; 如果突然来了一个优先级更高的任务, 还要去排队等着执行, 那就不太现实了, 所以引入了微任务.
简答的来说微任务就是用来插队的, 它就是要比宏任务先执行. 也就是说微任务的优先级要高于宏任务, 所有的微任务执行完毕之后才会去执行宏任务.
举个栗子: 医院排队交钱, 有一个人的家属要做手术; 急着交钱, 那还要人家慢慢排队等着交钱吗?
每次单个宏任务执行完毕后, 检查微任务队列是否为空, 如果不为空,会按照先入先出的规则全部执行完微任务后, 清空微任务队列, 然后再执行下一个宏任务,如此循环.