携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情
事件循环是什么?
就是一个执行任务队列的机制。
你了解浏览器的事件循环吗?为什么js在浏览器中有事件循环的机制?
JavaScript从诞生就是单线程。但是单线程就导致有很多任务需要排队,只有一个任务执行完才能执行后一个任务。如果某个执行时间太长,就容易造成阻塞,通过 Event loop 这个概念实现了非阻塞的操作
js是单线程的,(为什么js是单线程的),举个例子,如果有多个线程,一个线程删除了 DOM ,另一个线程要操作这个 DOM ,就会冲突,当然不只是这一种原因,为了避免这些问题,js是单线程的。
两种任务
宏任务:script代码块(整体代码块), setTImeout, setInterval, node 的 I/O 操作
微任务:new Promise().then, MutaionObserver(前端的回溯)
为什么有两种任务类型,只有宏任务不行吗
js代码执行过程中或者页面渲染过程中,宏任务都是保持着先进先出的原则,任务队列都是排队执行的,如果现在往任务队列里添加了一个事件,而且这个事件优先级非常高,需要立即执行,但因为宏任务的执行顺序,它肯定是最后执行的。所以只有宏任务是不可以的,引入了微任务的概念,处理一些优先级比较高的任务。
任务执行顺序
宏任务 ---> 微任务队列(如果在微任务中又碰到了微任务,会把微任务执行完毕) ---> 下一个宏任务
Node的事件循环和浏览器的事件循环有什么区别?
node宏任务
1.timers定时器 :已经进入任务队列的 setTimeout 和 setInterval 的回调函数
2.pending callback 待定回调:执行延迟到下一个循环迭代的 I/O 回调
3.idle,prepare:进系统内部使用
4.poll:检索新的 I/O 事件,执行与 I/O 相关的回调
5.check:执行 setImmediate 的回调函数
6.close callback:关闭事件,执行 socket.on('close', () => {}) 的回调
微任务和宏任务在node中的执行顺序 区别于版本(Node V10)
Node V10及以前:
- 执行完一类宏任务中的所有任务,按上面的宏任务分类
- 执行nextTick队列里的任务
- 执行所有微任务
Node V10及以后
- 和浏览器一致
输出顺序面试题
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("promise");
resolve();
}).then(function () {
console.log("promise2");
});
console.log("script end");
console.log("start");
setTimeout(() => {
console.log("1");
Promise.resolve().then(() => {
console.log("2");
});
}, 0);
new Promise(function (resolve) {
console.log("3");
setTimeout(() => {
console.log("4");
resolve("5");
}, 0);
}).then((res) => {
console.log("6");
setTimeout(() => {
console.log(res);
}, 0);
})
const p = function () {
return new Promise((resolve, reject) => {
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("1")
}, 0);
resolve("2");
});
p1.then((res) => {
console.log(res);
})
console.log("3");
resolve("4");
});
}
p().then((res) => {
console.log(res);
})
console.log("end");
setTimeout(() => {
console.log("setTimeout宏任务")
}, 0);
let test = async () =>{
console.log("promise 同步代码1")
let onePromise = await new Promise((resolve, reject) => {
resolve("success")
});
console.log("promise微任务执行2");
}
test();
new Promise((resolve, reject) => {
console.log("promise 同步代码")
resolve("success");
}).then((data) => {
console.log("promise微任务执行1")
})
console.log("end");
async function test() {
console.log("async1");
await new Promise((resolve, reject) => {
resolve(1)
});
console.log('async2');
};
setTimeout(function () {
console.log("setTimeout");
}, 0);
test();
new Promise(function (resolve) {
console.log("promise1");
resolve();
}).then(function () {
console.log("promise2");
});
console.log('end');