之前一直在面试,对于一些大厂面试题真的还是很注重原理和基础的,
还有就是数据结构和算法这种,校招的话,这些是很重要的,
前天和滴滴的人面试,问的真心觉得不难,而且也都是现在面试前端很常见的问题,
对于一道事件循环和微任务和宏任务的这道题,之前也是经常被面试到,但是一直没有放在心上,
本以为自己搞懂了,但是真正到了输出代码的时候,还是不清楚。
所有今天就要彻底弄懂事件循环到底是什么,以及他们到底是怎么执行的。
下面的讲述,以前天面试滴滴的那道事件循环题目为例子,进行展开
javaScript代码执行过程
JavaScript本身是一个单线程的任务,虽然在H5中新增了webWorker,支持了多线程任务,
但是他从本质上说还都是单线程任务,他们都是使用js的单线程任务模仿出来的,所以对js的执行过程,
下面还是画个图表示比较清楚:
微任务和宏任务
除了我们简单的同步任务和异步任务之外,我们还有一些宏任务和微任务:
常见的宏任务:setTimeout, setInterval, setImmediate, I/O, UI rendering
常见的微任务:process.nextTick, Promises, Object.observe(废弃), MutationObserver, promise.then
关于promise:
promise本身是同步的,但是他里面的回调函数是异步的,也就是new Promise()是同步的,但是他们里面的参数resolve()和reject()是异步的任务,
也就是宏任务队列
还有就是promise.then()这个方法也是微任务队列中的
执行过程
对于整个js的执行过程,先执行一个宏任务,然后执行宏任务里面所有的微任务,微任务执行完毕,
在开始执行一个宏任务,注意:script是一个宏任务,所以主线程上的任务第一个是宏任务
宏任务队列可以有多个,
微任务队列只有一个
执行分析
滴滴校招面试题目
var p1 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, 1);
})
setTimeout(() => {
console.log(2);
}, 0)
var p2 = new Promise((resolve, reject) => {
resolve(3)
console.log(4)
})
p2.then((res) => {
console.log(res)
}).then((res) => {
console.log(res)
})
p1.then((res) => {
console.log(res)
})
console.log(5)
console.log("1")
async和await在浏览器中运行
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')
执行结果画图如下:
测试二
async function testSometing() {
console.log("执行testSometing");
return "testSometing";
}
async function testAsync() {
console.log("执行testAsync");
return Promise.resolve("hello async");
}
async function test() {
console.log("test start...");
const v1 = await testSometing();
console.log(v1);
const v2 = await testAsync();
console.log(v2);
console.log(v1, v2);
}
test();
var promise = new Promise((resolve) => {
console.log("promise start..");
resolve("promise");
});
promise.then((val) => console.log(val));
setTimeout(() => { console.log("setTime1") }, 3000);
console.log("test end...")