学习async和await之前呢,不得不啰嗦一句!在这里如果还不了解异步和promise的请先看我更的上一篇文章JS中的promise
什么是async?
async是一种异步编程的解决方案:可以异步获取获取操作的信息,其实就是Generator函数的改进,背后原理就是promise
async如何使用和它的背后原理?
作为一个关键字放在函数前面,用来表示该函数是异步的。
async function fn1() {
return '小破船'
}
function fn2(){
return new Promise ((resolve,reject)=>{resolve('小破船')});
}
console.log(fn1());// Promise {<resolved>: "小破船"}
console.log(fn2());// Promise {<resolved>: "小破船"}
在上述代码中,我们可以了解到,使用async关键字的函数,表示该函数是异步的,当我们打印它的返回值,可以看到加了async关键字的函数fn1的返回值与没有加async关键字的函数fn2的返回值是一致的。就此也证明了async背后的原理也就是promise。既然是异步任务,那就是非阻塞的执行后面的代码,后面我们来证明一下。
证明async函数是异步执行。
上面已经阐述了,async函数返回的是一个Promise对象,既然是Promise对象, 那么我们就可以使用promise的then方法获取返回值。
async function fn1() {
return '小破船'
}
console.log("唐三"); //打印出来的顺序是 唐三 小舞 小破船
fn1().then((res)=>{
console.log(res);
});
console.log("小舞");
我们读取到了fn1的返回值,然而并没有阻塞掉后面的代码执行。上面我们使用了promise的then方法获取到promise成功状态下的返回值,既然可以使用then方法,当然可以只用catch方法获取失败状态下的返回值。在fn1函数里不是使用return而是使用throw来返回就可以得到失败状态的返回值,这了可以自己做测试,我就不再贴代码了。
await 如何使用
await需要配合async使用,await后面需要放置promise对象的表达式。await后面的promise表达式没执行完毕之前,下面的代码是阻塞掉的。
function fn2(name) {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(name+'借箭');
},3000);
});
}
async function fn1() {
const result=await fn2('小破船'); //fn2函数返回的是Promise表达式
console.log(result);
}
fn1(); //三秒之后 打印出 小破船借箭
以上面的代码可能还看不出await的真正作用是什么,如果我们用到好多个promise对象的返回值呢?
function fn2(num) {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(num+10);
},1000);
});
}
async function fn1() {
fn2(10).then((res1)=>{
fn2(20).then((res2)=>{
fn2(30).then((res3)=>{
console.log(res1+res2+res3);
});
});
});
}
fn1(); // 三秒之后打印出90
这样多层次的嵌套,如果是更多个promise呢?很明显await的出现就是光,请看下面代码。
function fn2(num) {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(num+10);
},1000);
});
}
async function fn1() {
const res1=await fn2(10);
const res2=await fn2(20);
const res3=await fn2(30);
console.log(res1+res2+res3);
}
fn1(); // 三秒之后打印出90
在这里我们是不是可以明白了await的作用,在这里我们不需要通过then方法去获取promise的返回值。这样我们用到多个promise对象的返回值是不是就方便很多了,就避免了promise的多层的嵌套。
- await在某些情况下可以阻塞后面的代码
- 可以方便的获取promise的返回值,避免深层的嵌套
如果看到了这里,你不给我点个赞,你不对劲你!!!