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回调来看