• ECMAScript 6 学习(一)generator函数


    1、ES2017标准引入async函数,那么async函数到底是个什么函数呢?

    async 是一个generator函数的语法糖。

    2、那么generator函数到底是什么函数ne?

    generator函数是ES6提供的一种异步编程解决方案,与传统函数完全不同。

    3、如何去理解generator函数呢?

    从语法上,可以认为generator函数是一个状态机,封装了多个内部状态。

    从返回内容上,可以认为generator函数是一个遍历器对象生成器,执行generator函数会返回一个遍历器对象,可以通过next函数一次遍历内部的每一个状态。

    从形式上,generator函数是一个普通函数,有两个特征,(1)function关键字与函数之间有一个*号;(2)函数内部使用yield表达式,定义不同的内部状态(yield)(yield意思是溢出)

    4、举个栗子

    (1)上述函数,定义一个generator函数helloSuningGenerator,他的内部有两个yield表达式(hello和suning),也就是说,该函数有三个状态:hello,suning,return语句(结束执行)。调用generator函数和普通函数一样,加(),但是generator函数并不执行,返回的是undefined。

    (2)调用遍历器对象使用next方法,使指针移向下一个状态。也就是说,每次调用next方法,内部指针就从函数头部或者上一次停下来的地方开始执行,遇到下一个yield表达式(或return语句)为止。yield表达式是暂停执行的标记,而next方法可以恢复执行。

    上面代码说明一共调用四次next方法。

    第一次调用,generator函数开始执行,直到遇到第一个yield表达式为止。next方法返回一个对象,返回对象的value值就是当前yield表达式的值hello。done属性值false,表示遍历还没有结束。

    第二次调用,generator函数从上次yield表达式停下来地方,一直执行到下一个yield表达式。next方法返回对象的value属性就是当前yield表达式的值world。done属性值false,表示遍历还没有结束。

    第三次调用,generator函数从上次yield表达式停下来的地方,一直执行到return语句(如果没有return语句,就执行到函数结束)。next方法返回的对象的value值属性,就是紧跟return与后边的表达式的值。done属性为true,以后调用next方法,done属性都是这个值。

    5、总结

    调用generator函数,返回一个遍历器对象,代表generator函数内部指针。以后,每一次调用遍历器对象的next方法,就会返回一个有着value和done两个属性的对象。

    value属性表示当前内部状态的值,是yield表达式后边那个表达式的值;

    done属性是一个布尔值,表示遍历时候结束。

    ------------------------------------------------

    那么yield表达式是什么ne ?

    yield表达式

    由于generator函数返回的遍历器对象,只有调用next方法才会遍历下一个内部状态,所以提供了一种可以暂停执行的函数。yield表达式就是暂停标志。

    遍历器对象的next方法的运行逻辑如下:

    (1)遇到yield表达式,就暂停执行后边的操作,并且将紧跟在yield后边的那个表达式的值,作为返回的对象的value属性值。

    (2)下一次调用next方法,在之前暂停的地方继续往下执行,知道遇到下一个yield表达式。

    (3)如果没有遇到新的yield的表达式,就一直运行到函数结束,直到return语句为止,并将return语句后边的表达式的值作为返回对象的value属性值。

    (4)如果该函数没有return语句,则返回对象的value属性值为undefined。

    注意:

    yield表达式后边的表达式,只有当调用next方法,内部指针指向该语句时才会执行。

    1、举个栗子

    上面代码中,23+78不会立即求值,只有在调用next方法将指针移到这一句时,才会求值。

    2、yield表达式和return语句相同点和区别?

    相同之处是:都能返回紧跟在语句后边的那个表达式的值,作为返回对象的value属性的值。

    不同之处是:(1)每次遇到yield,函数停止执行,下一次再从这个位置继续向后执行;而return语句不具备记忆功能。(2)一个函数中,只能执行一次(或者说一个)return语句,但是可以执行多次(多个)yield表达式,当时generator可以不用yield表达式,这样可以贬称一个暂缓执行的函数。

    上面代码中,f 如果是普通函数,在为gene赋值时才会执行。但是generator函数,变成只用调用next方法,函数f才会执行。

    3、举个栗子

    上面代码,yield必须在generator函数里面,不然会报错。

    4、举个栗子

    上面代码会产生句法错误,因为forEach方法的参数是一个普通函数,但是在里面使用了yield表达式。

    一种修改方法是改用for循环。

    上面代码还是显示undefined。

    5、举个栗子

     

    报错

    上面代码显示,没有定义

    上面代码显示,没有定义

     6、举个栗子

    ------------------------------------------------

    那么next方法参数

    yield表达式本身没有返回值,或者说是undefined。next方法可以带一个参数,该参数会被当成上一个yield表达式的返回值。

    上面代码先定义了一可以无限运行的generator函数f ,如果next方法没有参数,每次运行到yield表达式,变量reset的值总是undefined。当带一个参数true,变量reset就被重置为这个参数。

    generator函数从暂停状态到恢复状态运行,他的上下文(context)是不变的。通过next方法的参数,就可以实现generator函数运行的不同阶段,从外部向内部注入不同的值,从而调整函数行为。

    举个栗子

    上面代码中,第一次运行后,5+1=6;第二次运行next方法不带参数,y的值为2*undefined,除以3还是NAN,因此返回的对象的value值也是NAN。第三次运行next方法不带参数,z也是undefined,返回的对象的value属性等于5+NAN+undefined,即NAN。

    紧接着执行

    上面代码,第一次调用next方法,返回x+1=6;第二次调用next方法,上一次yield表达式的值设12,因此y=24;返回y/3=8;第三次调用next方法,将上一次yield表达式的值设为13,因此找3,这时候新,于4,所以return语句的值=42。

    注意:next方法的参数表示上一个yield表达式的返回值,所以第一次使用next方法时,传递参数是无效的。

  • 相关阅读:
    JS鼠标滚动事件
    [Harbor]Harbor简要介绍
    [Kubernetes]yaml文件详解
    [Kubernetes]安装和配置kubectl
    [Docker]如何批量删除镜像
    [Kubernetes]如何使用yaml文件使得可以向外暴露服务
    [Jenkins]CentOS7下Jenkins搭建
    [Docker]Docker拉取,上传镜像到Harbor仓库
    [Harbor]Docker登录Harbor仓库(HTTP方式)
    [Docker]CentOS7通过rpm包安装Docker
  • 原文地址:https://www.cnblogs.com/chengxs/p/7215039.html
Copyright © 2020-2023  润新知