前端面试:async/await的实现原理

1)async/await 就是 Generator 的语法糖,使得异步操作变得更加方便
2)async 函数就是将 Generator 函数的星号(*)替换成 async,将 yield 替换成await
3)async 是 Generator 的语法糖,这个糖体现在这几个方面:
async函数内置执行器,函数调用之后,会自动执行,输出最后结果,而Generator需要调用next或者配合co模块使用
更好的语义,async和await,比起星号和yield,语义更清楚了,async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果
更广的适用性,co模块约定,yield命令后面只能是 Thunk 函数或 Promise 对象,而async 函数的 await 命令后面,可以是 Promise 对象和原始类型的值
返回值是Promise,async函数的返回值是 Promise 对象,Generator的返回值是 Iterator,Promise 对象使用起来更加方便
4)async/await 函数的实现原理,就是将 Generator 函数和自动执行器,包装在一个函数里

function my_co(it) {
    return new Promise((resolve, reject) => {
        function next(data) {
            try {
                var { value, done } = it.next(data);
            }catch(e){
                return reject(e);
            }
            if (!done) { 
                //done为true,表示迭代完成
                //value 不一定是 Promise,可能是一个普通值。使用 Promise.resolve 进行包装。
                Promise.resolve(value).then(val => {
                    next(val);
                }, reject);
            } else {
                resolve(value);
            }
        }
        next(); //执行一次next
    });
}
function* test() {
    yield new Promise((resolve, reject) => {
        setTimeout(resolve, 100);
    });
    yield new Promise((resolve, reject) => {
        // throw Error(1);
        resolve(10)
    });
    yield 10;
    return 1000;
}

my_co(test()).then(data => {
    console.log(data); //输出1000
}).catch((err) => {
    console.log('err: ', err);
});

使用 async/await 需要注意什么?

1)await 命令后面的Promise对象,运行结果可能是 rejected,此时等同于 async 函数返回的 Promise 对象被reject。因此需要加上错误处理,可以给每个 await 后的 Promise 增加 catch 方法;也可以将 await 的代码放在 try…catch 中
2)多个await命令后面的异步操作,如果不存在继发关系,最好让它们同时触发 

3)await命令只能用在async函数之中,如果用在普通函数,会报错
4)async 函数可以保留运行堆栈

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值