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属性

  • 相关阅读:
    Android中使用WebView, WebChromeClient和WebViewClient加载网页
    Android清除本地数据缓存代码案例
    暴雪hash算法
    C++ 指向类的指针
    Qt VS Tools 的Qt Option add 不上qt版本的问题
    Dom4j完整教程详解
    java中charAt()方法的使用
    Linux环境下C++调试的三板斧
    (转载)Markdown进阶(更改字体、颜色、大小,设置文字背景色,调整图片大小设置居中)
    关于回调函数的理解
  • 原文地址:https://www.cnblogs.com/xinup/p/5052290.html
Copyright © 2011-2022 走看看