async await使用以及原理

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        <div>es6</div>
        <script type="text/javascript">
            // async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await,仅此而已
            // async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句
            // Generator 函数的执行必须靠执行器,所以才有了co模块,而async函数自带执行器和普通函数一样执行
            // async函数对 Generator 函数的改进:
            /*
            (1)内置执行器
            (2)更好的语义
            (3)更广的适用性
            (4)返回值是 Promise
            */

            async function fun() {
                try {
                    return await 123; // 等同于 return 123; 正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值
                } catch (err) {
                    console.log(err);
                }
            }
            // 只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数
            fun().then(res => {
                console.log(res, 'res') // 123 "res" 
            })

            async function fn1() {
                try {
                    // 如果有多个await命令,可以统一放在try...catch结构中
                    const res1 = await 123;
                    const res2 = await 456;
                    const res3 = await 789;
                    // await new Promise(function (resolve, reject) {
                    //    throw new Error('出错了');
                    // });
                    console.log(res1, res2, res3) // 先执行 123 456 789
                } catch (e) {
                    // throw new Error('出错了'); // async函数内部抛出错误,会导致返回的 Promise 对象变为reject状态。抛出的错误对象会被catch方法回调函数接收到
                }
                return await Promise.resolve('hello world');
            }

            fn1().then(res => console.log(res, 'res2')) // 后执行 hello world res2
            
            // async 函数的实现原理,就是将 Generator 函数和自动执行器,包装在一个函数里。
            async function fn(args) {
                // ...
            }
            // 等同于
            function fn(args) {
                return spawn(function*() {
                    // ...
                });
            }
            
            function spawn(genF) {
                return new Promise(function(resolve, reject) {
                    const gen = genF();
                    function step(nextF) {
                        let next;
                        try {
                            next = nextF();
                        } catch (e) {
                            return reject(e);
                        }
                        if (next.done) {
                            return resolve(next.value);
                        }
                        Promise.resolve(next.value).then(function(v) {
                            step(function() {
                                return gen.next(v);
                            });
                        }, function(e) {
                            step(function() {
                                return gen.throw(e);
                            });
                        });
                    }
                    step(function() {
                        return gen.next(undefined);
                    });
                });
            }
        </script>
    </body>
</html>

 

posted @ 2020-09-08 11:26  鱼樱前端  阅读(483)  评论(0编辑  收藏  举报