1什么是事件循环
js是单线程脚本语言,同一时间只能做一件事情,所以为了防止主线程的阻塞,在代码执行时分为同步任务和异步任务,所有的同步任务在主线程上执行,形成执行栈,而异步任务形成一个新的任务队列,又把任务队列中的异步任务分为宏任务和微任务,虽然他们都在任务队列中,但是它们却在不同的队列中,微任务的执行优先级大于宏任务,他们的结构如图所示。
**总结:**主线程会先执行同步任务,然后在执行异步任务,异步任务又分为微任务和宏任务,先执行微任务在执行红任务,全部执行完之后等待主线程调用,调用完后在去任务队列中查看是否有异步任务,这样循环往复的过程就是事件循环。
2哪些是宏任务,那些是微任务
宏任务:计时器(setTimeout、setInterval)等
微任务:promise.then()里面的、await返回的是一个promise对象,后面的相当于promise.then是微任务(为什么呢?请看下面)
3例
const promise = new Promise((resolve, reject) => {
console.log(1);
setTimeout(() => {
console.log("timerStart");
resolve("success");
console.log("timerEnd");
}, 0);
console.log(2);
});
promise.then((res) => {
console.log(res);
});
console.log(4);
上面这个代码:
1.从上至下,先遇到new Promise,执行该构造函数中的代码console.log(1)
2.然后碰到了定时器,将这个定时器中的函数放到下一个宏任务的延迟队列中等待执行
3.执行同步代码console.log(2)
4.跳出promise函数,遇到promise.then,但其状态还是为pending,这里理解为先不执行
5.执行同步代码console.log(4)
6.一轮循环过后,进入第二次宏任务,发现延迟队列中有setTimeout定时器,执行它
7.首先执行console.log(“timerStart”),然后遇到了resolve,将promise的状态改为resolved且保存结果并将之前的promise.then推入微任务队列
8.继续执行同步代码console.log(“timerEnd”)
9.宏任务全部执行完毕,查找微任务队列,发现promise.then这个微任务,执行它。
这下明白了吧,如果还不明白请看事件循环
4async、await和promise的关系
await 操作符用于等待一个方法执行,该方法执行完后,才会执行后面的。
function one() {
console.log(2)
}
function two() {
setTimeout(() => {
console.log(1)
},3000)
}
function run() {
two()
one()
}
//这样写
输出
2
1
他不会等待two执行完后在执行one
async function run() {
await two()
one()
}
输出
1
2
他会等待two执行完后在执行one
所以:将async转为promise会了吧
如果该值不是一个 Promise,await 会把该值转换为 resolved 的Promise,如果async函数里的await 是一个Promise对象,则这个Promise对象的resolve会触发后续代码的执行。换句话说await 语句之后的代码是await的这个Proimise对象的then逻辑。
例1
async function async1(){
console.log(1)
await 1//不是一个 Promise,await 会把该值转换为 resolved 的Promise
console.log(2)
}
let p = async1()
console.log(p)
//将上面代码转成promise
function async1() {
console.log(1)
new Promise(resolve => {
resolve(1)
}).then((res) => {
console.log(2)
})
}
let p = async1()
console.log(p)
例2
async function async1() {
console.log('a')
await async2()
console.log('b')
}
function async2() {
console.log('c')
}
//将上面代码转化成promise
function async1() {
console.log('a')
new promise((reslove)=> {
console.log('c')
reslove()
}).then((res) => {
console.log('b')
})
}
/**
async function async1() {
console.log('a')
await async2()
console.log('b')//这个才是异步
}
*/