async/await

137 阅读3分钟

前言

在我们使用Promise时,如果回调过多后,会导致后面then函数使用越来越多,使我们的代码不是很美观。在ES7时,为了用更简洁的方式写出类似Promise的异步请求,而无需链式调用Promise,出现了async/await。

async/await的基本使用

什么是async/await

async/await是ES7提出的基于Promise的异步请求解决方案。async/await其实就是Promise的语法糖,它是为了优化then的链式调用而开发出来的。从字面上来看,async是异步的缩写,await是等待的意思,所以我们很好理解async声明function是异步的,await是等待某个操作完成。从语法上规定,await只能出现在async函数中

async

async是一个加在函数之前的修饰符,它用于声明异步函数,返回值为一个Promise对象。

    async function test() {
        return 'hello'
    }
    async function as() {
        
    }
    console.log(test());
    console.log(as);
    console.log(as());
    test().then(res => console.log(res))

输出如下

image.png 从上面我们可总结出:

  1. async返回的是一个状态为fulfilled的Promise对象。
  2. 当async无返回值时,得到的Result的值undefined
  3. async定义的函数会默认返回一个Promise对象的resolve的值,对async函数可以直接使用then方法。

在Promise对象中,不仅有fulfilled状态,还有rejected状态。在async修饰的函数中,如果出现错误,我们可以使用.then或是.catch方法来抛出错误。

    async function test() {
        console.log(aaa);
    }
    console.log(test());
    test().then(res=>{
        console.log(res);
    },err => {
        console.log(err);
    })

image.png

await

await中文翻译为等待,语法为:

var value = await myPromise();

await的作用是暂停async function内部语句的执行,等待后面的Promise()处理完返回结果后,继续执行async function函数内部的剩余语句,上面的myPromise()是一个Promise对象,而自定义的变量value则用于获取Promise对象返回的resolve的状态值。 await必须在async function内使用,否则会语法错误;如果await跟的是其他值则会直接返回该值

function test1(x) {
        return new Promise(resolve => {
            setTimeout(() => {
                resolve(x)
            }, 3000)
        })
    }

    async function test2() {
        let result = await test1('hello')
        console.log(result);
    }
    test2()

在3秒后输出result

image.png


await操作符后面可以是任意值,当时Promise对象时,会暂停async function执行

    async function fn() {
    console.log(1);
    console.log(await 4); // 4 会被直接返回
    let result = await new Promise(function(resolve, reject) {
        setTimeout(function(){
            resolve(2);
        }, 2000);
    });
	console.log(result);
    console.log(3);
    
}
fn();

输出如下

image.png await会等待后面的Promise返回结果后才会执行async函数后面剩下的语句,也就是说如果Promise不返回结果(如resolve或reject),后面的代码就不会执行。

    async function fn() {
    console.log(1);
    await new Promise(function(resolve, reject) {
        setTimeout(function(){
            console.log(2);
        }, 2000);
    });
    console.log(3);
    
}
fn();

输出如下

image.png 函数会一直等待await返回结果(resolve或reject)才会执行剩下的语句,如果没有返回结果,就会一直等下去,await后面的语句就不会执行。
如果await后面的Promise返回一个reject状态的结果的话,则会被当成错误在后台抛出

    async function fn() {
    console.log(1);
    let result = await new Promise(function(resolve, reject) {
        setTimeout(function(){
            reject(2)
        }, 2000);
    });
    console.log(3);
    
}
fn();

输出如下

image.png

总结

  1. await只能在async函数中使用,否则会报错。
  2. async函数返回的是一个Promise对象,有无值看有无return值。
  3. await后面最好也是接Promise,虽然接其他的值也能达到排队的效果。
  4. async/await的作业是用同步的方法,执行异步操作