一、常见的宏任务和微任务
- 异步任务:宏任务和微任务,都属于异步任务
- 常见宏任务:
setTimeout
setInterval
script
- 常见微任务:
Promise.then()
process.nextTick
- 常见宏任务:
二、js执行顺序
1. 结论
- js是单线程执行,代码执行顺序是从上到下。先执行主线程中的同步任务,再执行微任务,最后执行宏任务
2. 具体执行过程
-
初始状态下,调用栈是空的,微任务队列也是空的,宏任务队列里有且只有一个 script 脚本(也就是整体代码)。所以首先执行并出队的就是宏任务队列中的整体代码。
-
整体代码作为宏任务进入调用栈之后,同步任务会直接执行,并且执行完以后出栈,异步任务会进行微任务和宏任务的划分,分别放入微任务队列和宏任务队列。
-
等到同步任务执行完了以后(也就是调用栈为空以后),就会去处理微任务队列,将微任务队列拉到调用栈里面。
-
微任务队列处理完了(调用栈为空)之后,再去处理宏任务队列,将宏任务队列拉到调用栈里面。
3. 注意
- 问题:微任务和宏任务的执行顺序,大多数人认为是先执行微任务,再执行宏任务。但是也有人认为是先执行宏任务,再执行微任务。
- 原因:代码执行前,script 脚本(整体代码)是放在宏任务队列中的,所以也可认为是先执行的宏任务。但实际上,从上面的具体执行过程中2、3、4步骤看来,是先执行微任务,再执行宏任务。
三、js 事件循环机制
js 是单线程执行的,前一个任务执行完,才能执行下一个任务,为了提高用户体验,将任务分为了同步任务和异步任务,同步任务会在主线程上排队执行,异步任务会被放进“任务队列”,同步任务执行完以后,主线程会从任务队列中读取“异步任务”,上一个异步任务执行完之后,再去读取下一个异步任务,主线程从"任务队列"中一个一个的读取“异步任务”的这个过程是循环不断的,这个就是 js 的事件循环机制。