理解async/await的关键所在是理解await的运行逻辑。首先各位同学脑海中需要有一个概念是,async/await仅仅是一个语法糖,不具有任何额外扩充的功能。 换句话说:所有能使用async/await语法的地方都能使用Promise来代替 下文将会把async/await与不同形式的JavaScript代码组合在一起,让我们来一起观察他的执行逻辑吧!
Promise + async/await
function m1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, 1000)
});
}
async function m2() {
const res = await m1()
console.log(res)
}
m2()
这是最常见的场景,await 会等待Promise的状态改为fullfilled。
- 如果成功,那么会将async函数剩余任务推入到微任务队列,
await后续的代码将变成:
async function m2() {
Promise.resolve(m1()).then((res)=>{
console.log(res)
})
}
- 如果失败,那么剩余任务不会被推入微任务队列执行,它会返回Promise.reject(err)
async function m2() {
Promise.reject(err)
}
最后的答案是:
1
我们来一道面试题
小面试题
async function test() {
console.log(1);
await console.log(2);
console.log(3);
}
console.log(4);
test()
console.log(5);
答案:
await如同他的语意,就是在等待,等待右侧的表达式完成。此时的await会让出线程,阻塞async内后续的代码,先去执行async外的代码。等外面的同步代码执行完毕,才会执行里面的后续代码。就算await的不是promise对象,是一个同步函数,也会等这样操作
41253
普通的值 + async/await
即使await右边非函数,只是一个普通的数值,但它本质上是将其转化为 Promise.resolve(),所以会返回一个成功的promise。我们通过几个题来仔细研究一下
有async和await的情况下打印什么
async function m1() {
return await 1
}
console.log(m1())
答案
有async没有await的情况下打印什么
async function m1() {
return 1
}
console.log(m1())
答案
这个await究竟是把他后面的数字进行了什么处理呢? 其实就是下面这个样子
async function m2() {
return await 3
}
上述等于
async function m2() {
return Promise.resolve(2)
}
await+普通函数
如果await 右边是一个函数,它会立刻执行这个函数,而且只有当这个函数执行结束后(即函数完成)!才会将async剩余任务推入微任务队列。 我们来看一道小demo:
function m1() {
console.log("我是m1")
return 1
}
async function m2() {
console.log("我是m2")
const res = await m1()
console.log("我是m2的中执行了m1()后的结果", res)
return res
}
console.log("我是外面的m2", m2())
看着大概能猜出来答案是不,我们把他转换一下然后在观察
function m1() {
console.log("我是m1")
return 1
}
function m2() {
console.log("我是m2")
return Promise.resolve(m1()).then((res) => {
console.log("我是m2的中执行了m1()后的结果", res)
})
}
console.log("我是外面的m2", m2())
答案为:
你有没有发现其实await是把他右边的函数立即执行了里面的函数,然后把他下面的函数存入then之中。而我们都知道的是,then函数内部的代码都将被推入微队列之中。 因此显而易见,这就是await在面对普通函数时的处理逻辑。
如上所述,我将上述所有的可能作了一个小例题出来,大家可以参考着答案研究一下
小例题
async function m1() {
return 1;
}
function m2() {
return Promise.resolve(2);
}
function m3() {
return new Promise((resolve, reject) => {
resolve(3);
});
}
async function m4() {
return Promise.resolve(4);
}
async function m5() {
return new Promise((resolve, reject) => {
resolve(5);
});
}
let res6;
async function m6() {
res6 = await m1();
return res6
}
let res7;
async function m7() {
res7 = m1();
return res7
}
console.log("m1()", m1())
console.log("m2()", m2())
console.log("m3()", m3())
console.log("m4()", m4())
console.log("m5()", m5())
console.log("m6()", m6(), res6)
console.log("m7()", m7(), res7)
以下是答案哟
从一道让我失眠的 Promise 面试题开始,深入分析 Promise 实现细节