前言
我们在面试的时候,经常会到那种面试题,给你一段很复杂的代码,然后让你写出执行结果。这类面试题非常考验我们对异步事件队列的应用,当然面对这类问题也是需要一定的方法的。这篇文章就是主要介绍如何处理复杂的异步嵌套逻辑。
快速分析一个复杂的异步嵌套逻辑,并掌握分析方法
console.log(1);
setTimeout(() => {
console.log(2);
setTimeout(() => {
console.log(8);
})
Promise.resolve().then(() => {
console.log(3)
});
});
new Promise((resolve, reject) => {
console.log(4)
setTimeout(() => {
console.log(10);
})
resolve()
}).then(() => {
console.log(5);
Promise.resolve().then(() => {
console.log(11)
});
setTimeout(() => {
console.log(13);
})
})
setTimeout(() => {
Promise.resolve().then(() => {
console.log(9)
});
console.log(6);
setTimeout(() => {
console.log(12);
})
})
console.log(7);
// 浏览器环境执行结果
// 1
// 4
// 7
// 5
// 11
// 2
// 10
// 6
// 13
// 3
// 9
// 8
// 12
// node环境执行结果:
// 1
// 4
// 7
// 5
// 11
// 2
// 3
// 10
// 6
// 9
// 13
// 8
// 12
分析方法
- 从头至尾执行一次代码,根据分类规则分至不同队列,new Promise(function)也是立即执行。setTimeout的回调函数属于宏队列(macrotask),resolve的回调函数属于微队列(microtask);
// 栈区
console.log(1);
console.log(4);
console.log(7);
// 宏队列
() => {
console.log(2);
setTimeout(() => {
console.log(8);
})
Promise.resolve().then(() => {
console.log(3)
});
}
() => {
console.log(10);
}
() => {
Promise.resolve().then(() => {
console.log(9)
});
console.log(6);
setTimeout(() => {
console.log(12);
})
}
// 微队列
() => {
console.log(5);
Promise.resolve().then(() => {
console.log(11)
});
setTimeout(() => {
console.log(13);
})
}
- 优先执行微任务队列,微队列执行过程中产生的微队列和宏队列置于队列末尾排序执行,而宏队列产生的微队列和宏队列于新的队列中等待。
执行微队列:(分类)
// 栈区
console.log(1);
console.log(4);
console.log(7);
///////
console.log(5);
// 微队列
() => {
console.log(11)
}
// 宏队列
() => {
console.log(2);
setTimeout(() => {
console.log(8);
})
Promise.resolve().then(() => {
console.log(3)
});
}
() => {
console.log(10);
}
() => {
Promise.resolve().then(() => {
console.log(9)
});
console.log(6);
setTimeout(() => {
console.log(12);
})
}
() => {
console.log(13);
}
- 此时新增了一个微队列console.log(11), 因为是微队列产生的,继续执行:
// 栈区
console.log(1);
console.log(4);
console.log(7);
///////
console.log(5);
//////
console.log(11);
// 微队列
// 宏队列
() => {
console.log(2);
setTimeout(() => {
console.log(8);
})
Promise.resolve().then(() => {
console.log(3)
});
}
() => {
console.log(10);
}
() => {
Promise.resolve().then(() => {
console.log(9)
});
console.log(6);
setTimeout(() => {
console.log(12);
})
}
() => {
console.log(13);
}
- 执行完微队列后执行宏队列
// 栈区
console.log(1);
console.log(4);
console.log(7);
///////
console.log(5);
///////
console.log(11);
///////
console.log(2);
console.log(10);
console.log(6);
console.log(13);
// 微队列
() => {
console.log(3)
}
() => {
console.log(9)
}
// 宏队列
() => {
console.log(8);
}
() => {
console.log(12);
}
- 接下来先执行微任务队列后执行宏任务队列
// 栈区
console.log(1);
console.log(4);
console.log(7);
///////
console.log(5);
///////
console.log(11);
///////
console.log(2);
console.log(10);
console.log(6);
console.log(13);
///////
console.log(3);
console.log(9);
console.log(8);
console.log(12);
// 微队列
// 宏队列