Async/await

简介: Async/await

Async/await

Async functions

async 被放置在一个函数前面:

async function a{
    return 1
}

函数前面的async一词意味着一个简单的事情:这个函数总是返回一个promise,如果代码中有return <promise>语句,JavaScript会自动把返回的这个value值包装成promise的resolved值。

例如,上面的代码返回resolved值为1的promise,我们可以测试一下

async function f() {
    return 1
}
f().then(alert) // 1

我们也可以显式的返回一个promise,这个将会是同样的结果:

async function f() {
    return Promise.resolve(1)
}
f().then(alert) // 1

所以,async确保了函数返回一个promise,即使其中包含非promise。够简单了吧?但是不仅仅只是如此,还有另一个关键词await,只能在async函数里使用,

Await

// 只能在async函数内部使用

    let value = await promise

    关键词await可以让JavaScript进行等待,直到一个promise执行并返回它的结果,JavaScript才会继续往下执行。

    以下是一个promise在1s之后resolve的例子:

    async function f() {
        let promise = new Promise((resolve, reject) => {
            setTimeout(() => resolve('done!'), 1000)
        })
        let result = await promise // 直到promise返回一个resolve值(*)
        alert(result) // 'done!'
    }
    f()

    函数执行到(*)行会‘暂停’,当promise处理完成后重新恢复运行, resolve的值成了最终的result,所以上面的代码会在1s后输出'done!'

    注意事项

    await字面上使得JavaScript等待,直到promise处理完成,然后将结果继续下去。这并不会花费任何的cpu资源,因为引擎能够同时做其他工作:执行其他脚本,处理事件等等。不能在常规函数里使用await如果我们试图在非async函数里使用await,就会出现一个语法错误:

    function f() {
       let promise = Promise.resolve(1)
       let result = await promise // syntax error
    }

    如果我们忘记了在函数之前放置async,我们就会得到这样一个错误。如上所述,await只能在async函数中工作。

    错误处理

    如果一个promise正常resolve,那么await返回这个结果,但是在reject的情况下会抛出一个错误,就好像在那一行有一个throw语句一样。

    async function f() {
        await Promise.reject(new Error('whoops!'))
    }

    和下面一样

    async function f() {
        throw new Error('Whoops!')
    }

    在真实的使用场景中,promise在reject抛出错误之前可能需要一段时间,所以await将会等待,然后才抛出一个错误。我们可以使用try-catch语句捕获错误,就像在正常抛出中处理异常一样:

    async function f() {
        try {
            let response = await fetch('http://no-such-url')
        } catch (err) {
            alet(err) // TypeError: failed to fetch
        }
    }

    如果发生了一个错误,控制会跳转到catch块。当然我们也能够捕获多行语句:

    async function f() {
        try {
            let response = await fetch('/no-user-here')
            let user = await response.json()
        } catch(err) {
            // 在fetch和response.json中都能捕获错误
            alert(err)
        }
    }
    f()

    总结

    放在一个函数前的async有两个作用:1.使函数总是返回一个promise2.允许在这其中使用await

    promise前面的await关键字能够使JavaScript等待,直到promise处理结束。然后:1.如果它是一个错误,异常就产生了,就像在那个地方调用了throw error一样。2.否则,它会返回一个结果,我们可以将它分配给一个值

    有了async/await,我们很少需要写promise.then/catch
    最后将代码奉上:可自己运行学习

    <template>
        <div class="asyncawait">
            <h1>Async/Await</h1>
            <Button type="primary" @click="handleClick">调用</Button>
        </div>
    </template>
    <script>
        export default {
            name: 'async-await',
            props: {},
            data () {
                return {}
            },
            watch: {},
            computed: {},
            components: {},
            mounted () {
                this.initFun ();
            },
            methods: {
                async func () {
                    return 1
                },
                handleClick () {
                    // console.log(this.func())
                    this.func ().then (res => {
                        console.log (res)
                    });
                    this.testResult ();
                },
                async initFun () {
                    let promise = new Promise ((resolve, reject) => {
                        setTimeout (() => resolve ('done!'), 3000)
                    });
                    console.log (333333333);
                    let result = await promise;
                    console.log (1111111111);
                },
                doubleAfter2seconds (num) {
                    return new Promise ((resolve, reject) => {
                        setTimeout (() => {
                            resolve (num)
                        })
                    })
                },
                async testResult () {
                    try {
                        let third = await this.doubleAfter2seconds ('阿')
                        let second = await this.doubleAfter2seconds ('好');
                        let first = await this.doubleAfter2seconds ('你');
                        console.log (first + second + third);
                    } catch (err) {
                        throw new Error ('askdfjaskdfjla');
                    }
                }
            }
        }
    </script>
    <style lang="less" scoped>
        .asyncawait {
            text-align: center;
        }
    </style>

    交流

    我是老礼,公众号「进军全栈攻城狮」作者 ,对前端技术保持学习爱好者。我会经常分享自己所学所看的干货,在进阶的路上,共勉!

    相关文章
    |
    9天前
    |
    前端开发 JavaScript
    Promise、async和await
    Promise、async和await
    13 0
    |
    3月前
    |
    前端开发 JavaScript
    什么是 async、await ?
    什么是 async、await ?
    |
    6月前
    |
    JSON 前端开发 JavaScript
    async/await的应用
    async/await的应用
    30 0
    |
    24天前
    |
    前端开发 JavaScript
    async/await
    async/await
    16 0
    |
    6天前
    |
    前端开发
    async、await
    async、await
    |
    6天前
    |
    前端开发
    |
    10天前
    |
    前端开发
    |
    20天前
    |
    JSON 前端开发 JavaScript
    |
    4月前
    |
    前端开发 JavaScript
    |
    5月前
    |
    前端开发
    for...in、for...of、for await...of
    for...in、for...of、for await...of
    24 1