JavaScript基础之async/await函数基础及原理

异步请求,我们第一时间想到的应该是promise,但是对于async/await函数也并不陌生。而且async/await函数在运用上可能会更加的方便简单。 那么我们就来剖析一下async/await函数。但是我想在细说async/await之前,还是要先说说generator函数。

generator:generator函数是es6的一种新的数据类型。一个generator看上去像一个函数,但可以返回多次。

function* generator () {
    yield '1111'
    yield '2222'
    yield '3333'
    return '44444'
}
let ge = generator()

generator函数和普通函数一样也是通过函数名+()去调用。但是调用完后并不会立即执行,它仅仅是创建了一个generator对象,还没有执行它,如果想要运行generator函数,那就需要通过遍历器对象的next方法。

let a = ge.next()    //    {value: '1111', done: false}
let b = ge.next()    //    {value: '2222', done: false}
let c = ge.next()    //    {value: '3333', done: false}
let d = ge.next()    //    {value: '4444', done: false}
let e = ge.next()    //    {value: undefined, done:true}

想要generator函数执行下一步,必须调用遍历起对象的next方法,使得指针移向下一个状态,也就是说,每调用next方法,内部的指针就从函数的头部或者上一次停下来的地方开始执行,知道遇到下一个yield表达式或者是return语句。由此可见,generator函数是分段执行的,yield表达式是暂停执行的标记。而next方法可以回复执行。也就是说上面的可以交出函数的之执行权。

以上这是对generator函数比较简单的介绍,下面我们来看看async/await函数。

其实,async/await函数就是generator函数的语法糖。async/await函数是在es7中推出的一套关于异步的终结解决方案。

function fun () {
    return '我是异步方法'
}

async function asyncTest () {
    try {
        let data = await fun()
        console.log(data)
    } catch (err) {
        console.log(err)
    }
}

这是async/await函数的最简单的用法。注:

  • async/await出现的异常是无法捕获的,所以这个时候,我们需要借助try...catch来捕获异常;
  • async/await函数的声明和普通函数没有什么区别,函数声明式,对象方法,class类方法,和箭头函数等都可以声明async/await函数;
  • 任何一个await后面的promise对象变为reject,那么整个async都会被中断;
  • async/await函数返回的是一个promise,必须等到内部所有的await后面的promise都执行完成之后,才能发生状态改变,除非遇到return或者是跑出错误,也就是说,只要async函数内部的异步操作执行完成,才会执行then方法指定的回掉函数;

上面我们说到async/await函数其实就是generator的语法糖,那么它实现的原理也就必然会和generator有关。所以,async函数实际上是对generator函数的改进:

  • async/await函数自带执行器,所以执行方式和普通函数的执行方式一样,通过函数名+()的方式执行
  • async/await比起*/yield函数语义上更加清楚
  • */yield函数中,yield命令之后只能是thunk函数或者是Promise对象,而async/await函数的await命令后面,可以是是promise和原始类型的值(数值,字符串和布尔值会自动转化成resolved的promise对象)
  • async函数的返回值是一个promise对象,这比generator函数的值是一个Iterator对象方便很多,可以是使用then方法指定下一步的操作
  • 进一步来说,async/await函数完全可以看作是多个异步操作,包装成的一个promise对象,而await命令就是内部then命令的语法糖

当然async/await的实现也是基于promise,async函数其实就是把promise做了一个包装,因为await本身返回的也是一个Promise,它只是把await后面的代码放到了await返回的Promise的.then后面,以此来实现的。看下面的俩段代码,他们是等价的。

getConstant() {
   return 1
 }

 async getAsyncConstant() { 
  return 1
 }

 async getPromise() {
  return new Promise((resolved, rejected)=> {
    resolved(1)
  });
 }

 async test() {
  let a = 2
  let c = 1
  await getConstant();
  let d = 3
  await getPromise();
  let d = 4
  await getAsyncConstant();
  return 2
 }
function getConstant() {
   return 1;
}

function getAsyncConstant() {
  return Promise.resolve().then(function () {
   return 1;
  });
}

function getPromise() {
  return Promise.resolve().then(function () {
   return new Promise((resolved, rejected) => {
    resolved(1);
   });
  });
}

  test() {
    return Promise.resolve().then(function () {
       let a = 2;
       let c = 1;
       return getConstant();
     }).then(function () {
       let d = 3;
       return getPromise();
     }).then(function () {
       let d = 4;
       return getAsyncConstant();
     }).then(function () {
       return 2;
     });
 }

就是这样。。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值