Event loop 事件循环

182 阅读2分钟

call stack (调用栈) 作用: 所有代码执行地方

Event loop 包括两个队列 宏观队列(存放 macrotask) 微观队列(存放 microtask)

默认规则:Event loop 优先调用 微观队列中的任务 当微观队列为空时才会调用 宏观队列

默认规则:Event loop 优先调用 微观队列中的任务 当微观队列为空时才会调用 宏观队列

默认规则:Event loop 优先调用 微观队列中的任务 当微观队列为空时才会调用 宏观队列

最常见的macrotask (浏览器中常用)

  setTimeout	setInterval	DOM	Ajax

最常见的microtask (浏览器中常用)

Promise	async/await

先来看一下这张图

先写一段简单的代码

console.log('start'); // 1.call stack 执行 console 输出 start

// 2. call stack 执行setTimeout(WEB API) 
// 将 匿名函数 ()=>{console.log("setTimeout")}推入macroqueue(宏观队列) 等待
setTimeout(()=>{  // 6. Event loop 最后轮询 宏观任务 推入 call stack 执行 输出 setTimeout
  console.log("setTimeout");
});
// 3. call stack 执行 Promise
// 将 then 匿名函数 res=>{console.log(res)} 推入microqueue(微观队列) 等待
Promise.resolve('promise').then(res=>{ // 5. Event loop 优先轮询 微观任务 推入 call stack 执行 输出 promise
  console.log(res);
})
// 4. call stack 执行 console 输出 end
console.log('end');
// 最后结果:
// start
// end
// promise
// setTimeout

再来一段变异版

console.log('start');
// 重点
// call stack 执行 new Promise中的函数
// 把then回调推入microqueue(微观队列)等待轮询
// 当call stack 为空时调用
new Promise((resolve)=>{
  console.log('Promise 1');
  resolve('Promise 2');
}).then(res => {
  console.log(res);
});
console.log('end');
// 最后结果:
// start
// Promise 1
// end
// Promise 2

下面让async/await加入

// 技巧:先看执行后看声明
// 执行1 
console.log('start'); // 输出1 start

// 执行2 
setTimeout(()=>{ // 代码推入 macroqueue (宏观队列)
  console.log("setTimeout");// 输出7 setTimeout
});

// 执行4 
async function async1(){
  // 执行5
  console.log("async1 start"); // 输出2 async1 start
  // 要执行看声明 
  await async2(); 
  //  await async2() 后的代码等价于promise中then
  console.log("async1 end");  // 代码推入 microqueue (微观队列) 输出6 Promise
}

// 执行6
function async2(){
  console.log("async2");// 输出3 async2 
}

 // 执行3 
Promise.resolve('Promise').then(res =>{// 执行promise完 then回调推入 microqueue (微观队列)
  console.log(res); // 输出5 Promise
});

// 要执行看声明 
async1(); 

console.log('end');// 输出4 end
// start
// async1 start
// async2
// end
// Promise
// async1 end
// setTimeout

async/await重点就是 await 调用的函数后面要当做promise中的then回调来看