async/await函数的使用和实现原理

使用

对比普通函数,注意打印顺序,addB函数先打印,addA后打印,结果也不一样。

function promise() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(3)
    })
  })
}
async function addA() {
  var re = await promis();
  console.log(re)
}

function addB() {
  var re = promis();
  console.log(re)
}

addA()
addB()

 

 


var promis = function() {
  return Promise.resolve(3)
}

async function add() {
  var re = await promis()
}
add().then(function(res) {
  console.log(res) // undefined
}).then((res) => {
  console.log(res) // undefined
}).then((res) => {
  console.log(res) // undefined
  
})

函数没有返回值,调用后可以无限的调用then函数,结果是undefined。因为async函数的返回值是promise,而promise函数的then函数默认return 了一个新的promise,所以这里可以实现链式调用。 

给函数加一个返回值,打印结果发生了改变,返回值可以在then函数中拿到。

async function add() {
  var re = await promis();
  return re
}
add().then(function(res) {
  console.log(res) // 3
}).then((res) => {
  console.log(res) // undefined
}).then((res) => {
  console.log(res) // undefined
  
})

处理异常,虽然async函数也可以捕获异常,但是,如果异步请求异常了,async函数内部await下面的内容不会再执行了。

function promise() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log(nam)
      resolve(3)
    })
  })
}

async function addB() {
  var re = promis();
  console.log(4) // 这里无法执行
}
addB().then().catch(function() {
  console.log(5) // 这里可以执行
})

使用try catch解决上面问题:

async function addB() {
  try {
    var re = promis();
  } catch (error) {
    console.log(error) //这里可以执行
  }
  
  console.log(4) // 这里可以执行
}
addB().then().catch(function() {
  console.log(5) // 这里不执行
})

 

实现一个简单的async/await

如上,我们掌握了Generator函数的使用方法。async/await语法糖就是使用Generator函数+自动执行器来运作的,返回值是一个 promise。 如果想进异步了解Generator函数+自动执行器,可以移步《Generator函数的使用和原理》

es6新增的Generator函数是用来解决异步问题的,那为什么不直接使用Generator函数呢?是因为Generator函数不能直接执行,需要手动调用,或者结合自动执行器来使用。而async/await函数内部自带了自动执行器,使用起来方便,美观。

 

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

            
            // async 函数的实现原理,就是将 Generator 函数和自动执行器,包装在一个函数里。
            async function fn(args) {
                // ...
            }
            // 等同于 里面的await 换成 yield
            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); // 这也是为什么 不使用try catch的话,异常异步请求后面的代码不再执行的原因,从这里不再继续调用nex()方法了。
                        }
                        Promise.resolve(next.value).then(function(v) {
                            step(function() {
                                return gen.next(v);
                            });
                        }, function(e) {
                            step(function() {
                                return gen.throw(e); // 这里可以解释为什么async 函数需要使用try catch来捕获异常,生成器函数的throw,会让代码到catch里面
                            });
                        });
                    }
                    step(function() {
                        return gen.next(undefined);
                    });
                });
            }

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值