描述
JavaScript 的执行是单线程的,后面的任务需要等待前面的任务完全完成后,再去执行。 DOM 事件(文件的加载等)、定时器、网络请求等事件,并不会消耗 CPU,这些事件无需等候,所以出现了异步。 主线程进行中,将异步事件交给专有模块去处理,当主线程完成后,再去读取异步事件归并到主线程进行处理。
事件流程
主线程读取代码,形成响应的堆和任务栈 遇到异步的时候,将事件加入到任务队列 主线程执行完毕后,查询任务队列,执行队列中的事件 按顺序,先执行微任务 再次读取任务队列,如果不再有微任务,开始按顺序执行宏任务 队列执行完毕
let timeOut1 = setTimeout ( ( ) => {
console. log ( '1' ) ;
let promise1 = new Promise ( function ( resolve, reject ) {
console. log ( '2' ) ;
let timeOut2 = setTimeout ( ( ) => {
console. log ( '3' )
} , 0 ) ;
resolve ( ) ;
} ) . then ( function ( ) {
console. log ( '4' )
} )
} , 0 ) ;
console. log ( '5' ) ;
let timeOut3 = setTimeout ( ( ) => {
console. log ( '6' )
} , 0 )
async function func1 ( ) {
console. log ( '7' ) ;
await func2 ( ) ;
console. log ( '8' ) ;
}
function func2 ( ) {
console. log ( '9' ) ;
}
func1 ( ) ;
let promise2 = new Promise ( function ( resolve, reject ) {
console. log ( '10' ) ;
resolve ( ) ;
} ) . then ( function ( ) {
console. log ( '11' ) ;
} ) . catch ( function ( ) {
console. log ( '12' ) ;
} )
console. log ( '13' )
将 timeOut1 加入任务队列 A 主线程,打印 5 将 timeOut3 加入任务队列 A 主线程,执行 func1,打印 7 执行 func2,打印 9 将 await 定义域内后面的事件统一添加到任务队列 A 主线程,执行 promise2,打印 10 将 promise2.then 添加到任务队列 A 主线程,打印 13 当前主线程执行完毕,开始读取任务队列 A 当前任务队列 A:timeOut1、timeOut3、await、promise2.then 先执行微任务,后执行宏任务 执行 await,打印 8 当前任务队列 A:timeOut1、timeOut3、promise2.then 执行 promise2.then,打印 11 当前任务队列 A:timeOut1、timeOut3 任务队列 A,所有微任务执行完毕,开始按顺序执行宏任务 执行 timeOut1,打印 1 执行 promise1,打印 2 将 timeOut2 加入任务队列 A 将 promise1.then 加入任务队列 A 当前任务队列 A:timeOut3、timeOut2、promise1.then 先执行微任务,后执行宏任务 执行 promise1.then,打印 4 当前任务队列 A:timeOut3、timeOut2 任务队列 A,所有微任务执行完毕,开始按顺序执行宏任务 执行 timeOut3,打印 6 执行 timeOut2,打印 3