web前端高级JavaScript - JavaScript中事件(任务)循环机制EventLoop及面试题

Js中的事件循环机制EventLoop

  • 在JavaScript代码自上而下执行过程中,分为同步任务和异步任务,异步任务又分为异步微任务和异步宏任务,同步任务也是宏任务。

    • 常见的异步微任务
      • promise
      • async/await
      • requestAnimationFrame
    • 常见的异步宏任务
      • 定时器setTimeout
      • ajax(HTTP网络请求)
      • 事件绑定
  • 在主线程自上而下执行js代码时,同步宏任务会优先执行,如果遇到上述异步任务,不会立即执行,而是把这些异步任务存放到EventQueue任务队列中进行排队等待,主线程中的同步任务继续向下执行

  • 当所有同步任务执行完成后,再优先执行所有异步微任务,待所有异步微任务执行完成后,最后再执行异步宏任务

    • 在执行过程中会严格按照该顺序执行
    • 即使在同步任务没有执行完,但异步任务中已经有到达执行条件了,那也不能执行,必须要等待同步任务执行完成
    • 不管什么时候放置的微任务,也不管异步宏任务是否已经到达执行条件了,只要异步微任务存在,就永远不会执行异步宏任务
  • 事件循环机制EventLoop:主线程自上而下,已经执行完所有同步任务,主线程空闲下来,开始到EventQueue任务队列中找异步任务(优先查找微任务),找到任务后拿到主线程中执行,此时主线程又被占用不能处理其他事情,当这个异步任务执行完,主线程又空闲,继续到EventQueue中查找其它异步任务执行,这就是事件循环机制。
    在这里插入图片描述

关于同步异步的一些面试题

let body = document.body;
body.addEventListener('click', function(){
	Promise.resolve().then(() => {
		console.log(1);
	});
	console.log(2);
});
body.addEventListener('click', function(){
	Promise.resolve().then(() => {
		console.log(3);
	});
	console.log(4);
});
//答案:2 1 4 3
//======================================================================
console.log('start');
let intervalId;
Promise.resolve().then(() => {
    console.log('p1');
}).then(() => {
    console.log('p2');
});
setTimeout(() => {
    Promise.resolve().then(() => {
        console.log('p3');
    }).then(() => {
        console.log('p4');
    });
    intervalId = setInterval(() => {
        console.log('interval');
    }, 3000);
    console.log('timeout1');
}, 0); 
//答案:start p1 p2 timeout1 p3 p4 interval....
//======================================================================
setTimeout(() => {
    console.log('a');
});
Promise.resolve().then(() => {
    console.log('b');
}).then(() => {
    return Promise.resolve('c').then(data => {
        setTimeout(() => {
            console.log('d')
        });
        console.log('f');
        return data;
    });
}).then(data => {
    console.log(data);
}); 
//答案:b f c a d
//======================================================================
function func1() {
    console.log('func1 start');
    return new Promise(resolve => {
        resolve('OK');
    });
}
function func2() {
    console.log('func2 start');
    return new Promise(resolve => {
        setTimeout(() => {
            resolve('OK');
        }, 10);
    });
}
console.log(1);
setTimeout(async () => {
    console.log(2);
    await func1();
    console.log(3);
}, 20);
for (let i = 0; i < 90000000; i++) {} //循环完大于80ms左右
console.log(4);
func1().then(result => {
    console.log(5);
});
func2().then(result => {
    console.log(6);
});
setTimeout(() => {
    console.log(7);
}, 0);
console.log(8); 
//答案:1 4 [func1 start] [func2 start] 8 5 2 [func1 start] 3 7 6
//======================================================================
setTimeout(() => {
    console.log(1);
}, 20);
console.log(2);
setTimeout(() => {
    console.log(3);
}, 10);
console.log(4);
console.time('AA');
for (let i = 0; i < 90000000; i++) {
    // do soming
}
console.timeEnd('AA'); //=>AA: 79ms 左右
console.log(5);
setTimeout(() => {
    console.log(6);
}, 8);
console.log(7);
setTimeout(() => {
    console.log(8);
}, 15);
console.log(9);
//答案:2 4 [AA:79ms] 5 7 9 3 1 6 8
//======================================================================
async function async1() {
    console.log('async1 start');
    await async2();
    console.log('async1 end');
}
async function async2() {
    console.log('async2');
}
console.log('script start');
setTimeout(function() {
    console.log('setTimeout');
}, 0)
async1();
new Promise(function(resolve) {
    console.log('promise1');
    resolve();
}).then(function() {
    console.log('promise2');
});
console.log('script end');
//答案:[script start] [async1 start] async2 promise1 [script end] [async1 end] prmise2 setTimeout

画图分析

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值