异步编程解决方案async/await

177 阅读2分钟

这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战」。

一、async/await

1.1 基本含义

async是异步的意思,await是等待的意思。从意思上我们就可以看出,async是声明一个函数式异步的,而await是等待一个异步函数执行完成。

async/await其实是generator函数的语法糖。

1.2 async如何处理返回值

  • 那么async函数是怎么处理他的返回值的呢?
async function foo() {
    return 'hello'
}

console.log(foo())

实现上边的代码,我们可以看出,返回的是一个Promise对象。所以,async函数返回值是一个Promise对象。而且,如果在函数体中直接return一个直接量,async会把这个直接量通过Promise.resolve()封装成Promise对象。

1.3 await的使用

  • await必须在async内部使用,不能单独是使用

  • 看下面代码

async function foo() {
    let res = await 'hello'
    console.log(res);
}

foo()

上边的代码确实能够正常运行,但其实是没有意义的,因为await后边跟的应该是一个异步操作,这样才能实现其意义:等待异步函数执行完成在调用之后的代码,如下:

function timeout() {
    return new Promise((resolve,reject) => {
        setTimeout(() => {
            resolve(1)
        },1000)
    })
}
async function foo() {
    let res = await timeout()
    console.log(res);
    console.log(2);
    
}

foo()

上边的代码会在一秒之后才打印出结果,这就是await的作用。而且你知道是先输出1还是先输出2呢?不放动手试一试,或者跳到文章最后寻找答案呦。

1.4 async/await 处理resolve和reject

async/await 处理resolve和reject时也是在函数调用后用then和catch

function timeout() {
    return new Promise((resolve,reject) => {
        setTimeout(() => {
            resolve('success')
            // reject('fail')
        },1000)
    })
}
async function foo() {
    return await timeout()
}

foo().then( res =>{
    console.log(res)
}).catch(err =>{
    console.log(err)
})

1.5 用async/await处里回调地狱问题

我们在之前学习promise的时候封装了一个ajax,连续处理三次请求(文章链接),我们也可以用async/await来改造,代码如下:

function ajax(url,callback) {
    var xmlHttp 
    // 创建XMLHttpRequest
    if(window.XMLHttpRequest) {
        xmlHttp = new XMLHttpRequest()
    }else { //兼容IE7之前的浏览器
        xmlHttp = new ActiveXObject('Microsoft.XMLHTTP')
    }
    
    //发送请求 
    xmlHttp.open('GET',url,true)
    xmlHttp.send()
    
    // 响应数据
    xmlHttp.onreadystatechange = function() {
        if(xmlHttp.readyState === 4 && xmlHttp.status === 200){
            var res = JSON.parse(xmlHttp.responseText)
            callback(res)
        }
    }
}

function request(url) {
    return new Promise(resolve => {
        ajax(url, res=> {
            resolve(res)
        })
    })
}

async function getData() {
    let res1 = await request('/api1')
    let res2 = await request('/api2')
    let res3 = await request('/api3')
}

总结

其实,我认为async/await最大的好处就是让一步代码看起来写起来更像同步代码。而且对比promise更加的优雅,在处理很多请求,很多异步操作而且互相依赖关系很强时,用async/await看起来会更加的舒服、简洁,更加的好维护。

答案:1 2