zoukankan      html  css  js  c++  java
  • generator函数学习笔记

    一、基本概念

    Generator函数是一种可以暂停执行,返回iterator对象的函数,yield是暂停标识

    function* gen(){
        yield 1;
        yield 2;
    }

    Generator函数在function后面有一个*,内部有yield语句

    function* gen(){
        yield 1;
        yield 2;
        return '1'
    }
    
    let g = gen(); //调用Generator函数返回遍历器对象
    console.log(g.next())//{"value":1,"done":false} 
    console.log(g.next())//{"value":2,"done":false}

    console.log(g.next())//{"value":"1","done":true}
     console.log(g.next())//{"value":undefined,"done":true}
    
    

    如果内部没有yield命令,generator函数和普通函数没有差别,只是暂停执行。

    二、for of

    generator函数返回遍历器对象,可以用for of遍历

    function* gen(){
        yield 1;
        yield 2;
        return '1'
    }
    
    for(let i of gen()){
      console.log(i)
    }
    //1
    //2

    三、next return throw

    iterator对象都有这三个方法,但一般的内置默认的Symbol.iterator返回的对象没有return throw方法。

    1.next方法可以向generator函数内部传递数据  yield命令本身没有返回值,next方法的参数可以用作yield的赋值。

    function* gen(){
        yield 1;
        let a = yield 2;
        console.log(a) //10
        return a
    }
    let g = gen();
    console.log(g.next())//{"value":1,"done":false}
    console.log(g.next()) //{"value":2,"done":false} 10
    console.log(g.next(10)) //{"value":10,"done":false}

    2.Generator函数返回的遍历器对象值,还有一个return方法,可以返回给定的值,并且终结遍历Generator函数。

    function* gen() {
      yield 1;
      yield 2;
      yield 3;
    }
    var g = gen();
    g.next()        // { value: 1, done: false }
    g.return("foo") // { value: "foo", done: true } 遍历结束
    g.next()        // { value: undefined, done: true }

    3.Generator函数返回的遍历器对象,都有一个throw方法,

    a.可以在函数体外抛出错误,然后在Generator函数体内捕获。

    b.内部抛出错误,而内部没有try catch捕获,外部可以捕获

    c.generator函数内部抛出错误捕获了,不会阻止代码运行

    var g = function* () {
        try {
          yield;
        } catch (e) {
          console.log('内部捕获', e);
        }
      }
    var i = g(); i.next(); try { i.throw('a'); i.throw('b'); } catch (e) { console.log('外部捕获', e); }
    //内部捕获 a
    //外部捕获 b

    第一个错误被Generator函数体内的catch语句捕获,此时Generator函数就算执行完成了,不会再继续执行了。遍历器对象i第二次抛出错误,由于Generator函数内部的catch语句已经执行过了,不会再捕捉到这个错误了,所以这个错误就被抛出了Generator函数体,被函数体外的catch语句捕获。

    要注意遍历器对象的throw与全局的throw的区别 后者只能被函数体外的catch捕获。

    四、yield*

    yield* 后面是遍历器对象  可用于在generator函数内调用另一个generator函数 yield*相当于运用了for of

    五、generator用于异步的同步表示

    因为generator函数是可以暂停的,且yield是同步的,所有后一个yield肯定在上一个结束后才运行。

    六、generator与协程

    协城:可以交换执行权,达到“伪并行”的状态,其实在同一时间还是只有一个函数在运行

    Generator函数是ECMAScript 6对协程的实现,但属于不完全实现。Generator函数被称为“半协程”(semi-coroutine),意思是只有Generator函数的调用者,才能将程序的执行权还给Generator函数。如果是完全执行的协程,任何函数都可以让暂停的协程继续执行。

    七、generator的this

    Generator函数总是返回一个遍历器,ES6规定这个遍历器是Generator函数的实例,也继承了Generator函数的prototype对象上的方法。

    function* g() {
      this.a = 11;
    }
    
    let obj = g();
    obj.a // undefined

    Generator函数返回的总是遍历器对象,而不是this对象。所有obj拿不到a属性

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 交换Easy
    Java实现 蓝桥杯VIP 算法提高 多项式输出
    Java实现 蓝桥杯VIP 算法提高 多项式输出
    Java实现 蓝桥杯VIP 算法提高 多项式输出
    Java实现 蓝桥杯VIP 算法提高 多项式输出
    Java实现 蓝桥杯VIP 算法提高 多项式输出
    Java实现 蓝桥杯VIP 算法训练 矩阵乘方
    QT中给各控件增加背景图片(可缩放可旋转)的几种方法
    回调函数实现类似QT中信号机制
    std::string的Copy-on-Write:不如想象中美好(VC不使用这种方式,而使用对小字符串更友好的SSO实现)
  • 原文地址:https://www.cnblogs.com/xinup/p/5052290.html
Copyright © 2011-2022 走看看