【问】js中事件循环是什么?宏任务和微任务又是什么?
【答】
事件循环:
js的特点是单线程,即同一时间只能干一件事情,当然这是基于他的主要运行环境是浏览器而这样设计的(创立js之初,主要运行在浏览器环境。其一这样的场景没必要用复杂的多线程;其二单线程设计避免了很多复杂的同步问题,如多线程同时操作dom)。但后来的发展,js现在也可以运行在非浏览器环境如nodejs中,但依然是单线程)。但单线程就意味着所有任务需要排队运行,如某一个任务耗时很长(如网络请求等),就会让后面的任务一直处于等待状态,为了解决这个问题,js中将任务分为两类:同步任务和异步任务。同步任务是在主线程上排队马上执行的任务,异步任务是延后执行(至少要等到同步任务执行完毕后),不进入主线程而在任务队列中的任务。运行机制是:
1. 所有同步任务都在主线程执行;
2. 任务队列中存放的是某些有了运行结果的异步任务的事件;
3. 所有同步任务执行完毕后,就读取任务队列中该事件对应的异步任务,开始执行;
4. 不断循环第3步。上面这个循环机制即事件循环机制。
宏任务和微任务:
宏任务:setTimeout、setInterval、dom事件、Ajax请求等
微任务:promise,async/await 等
执行时机:微任务 > DOM渲染 > 宏任务
【测试】
var childDom = document.createElement("div");
childDom.innerHTML = "dom测试";
document.body.appendChild(childDom);
console.log(1);
Promise.resolve().then(() => {
console.log('2 promise');
alert('alert promise');
});
setTimeout(() => {
console.log('3 setTimeout');
alert('alert setTimeout');
}, 0);
console.log(4)
//打印顺序是
//1
//4
//2 promise
//3 setTimeout
//【结论】通过测试发现:微任务(promise)最早执行,接着是dom渲染执行(使用alert是为了阻止继续执行),最后是宏任务(setTimeout)执行。
参考1:JavaScript 运行机制详解:再谈Event Loop
参考2:事件原理讲解,超级硬核-哔哩哔哩
参考3:宏任务和微任务 - 哔哩哔哩