JS是单线程的,每次只能作一件事情。像如下这种状况,代码会按顺序执行,这个就叫同步。ajax
console.log(1);
console.log(2);
console.log(3);
复制代码
如下代码会输出二、三、1,像这种不按顺序执行的,或者说代码执行中间有时间间隙的,叫异步。数组
setTimeout(() => {
console.log(1);
}, 0);
console.log(2);
console.log(3);
复制代码
一个浏览器一般有如下几个常驻的线程:浏览器
渲染线程和JS引擎线程是不能同时进行的。也就是说在执行代码时,渲染会挂起;渲染DOM时,代码也不会执行。 虽然JS是单线程,可是浏览器是多线程的,在遇到像setTimeout、DOM事件、ajax等这种任务时,会转交给浏览器的其余工做线程(上面提到的几个线程)执行,执行完以后将回调函数放入到任务队列。bash
// eventLoop是一个用做队列的数组
// (先进,先出)
var eventLoop = [ ];
var event;
// “永远”执行
while (true) {
// 一次tick
if (eventLoop.length > 0) {
// 拿到队列中的下一个事件
event = eventLoop.shift();
// 如今,执行下一个事件
event();
}
}
复制代码
咱们能够用上面的代码来想像一下JS的执行状况。
JS主线程,就像是一个while循环,会一直执行下去。在这期间,每次都会查看任务队列有没有须要执行的任务(回调函数)。在执行完一个任务以后, 会继续下一个循环,直到任务队列全部任务都执行完为止。多线程
任务队列又分微任务队列和宏任务队列异步
也就是说执行微任务队列 会将队列中的全部微任务执行完 而执行宏任务队列 每次只执行一个宏任务 而后从新开始下一个循环 咱们能够看看如下代码函数
setTimeout(() => {
console.log(3)
new Promise((resolve, reject) => {
console.log(5)
resolve()
}).then(console.log(6))
}, 0)
setTimeout(() => {
console.log(4)
}, 0)
new Promise((resolve, reject) => {
console.log(1)
resolve()
}).then(console.log(2))
复制代码
输出是1 2 3 5 6 4oop
咱们来分析一下代码的执行过程ui