学习笔记:Generator函数

183 阅读2分钟

Generator函数是ES6提供的一种异步编程解决方案,普通函数一旦执行,除非遇到return,不然就一直往下运行,也不能从外部再传值进入函数体。而Generator函数,运行期间是可以打断。它相对于普通函数,有如下特征

  1. function关键字和函数名之间有个" * "号 

    function* generator(){}
    
  2. 在函数体内可以使用yield关键字,把函数的执行流程挂起。如果用在另一个表达式中,必须放在圆括号里面。在一个Generator函数里面执行另一个Generator函数,前面也要加关键字

    function* generator(){
        yield 'status'    
        console.log('abc' + (yield def))
        return 'hello'
    }
    
    function* gen(){
        yield generator()
    }
    
    
  3. 调用generator函数,不会返回运行结果,而是返回一个遍历器对象。这个对象有next方法和return方法。

    function* generator(){
        yield 'status 1'
        yield 'status 2'
        return 'hello'
    }
    
    console.log(generator()) //generator {<suspended>}
    
    const obj = generator()
    
    obj.next() // {value: "status 1", done: false}
    
    obj.next() // {value: "status 2", done: false}
    
    obj.next() // {value: "hello", done: true} ,true 表示所有状态都遍历完毕
    
    obj.next() // {value: undefined, done: true} , 没有状态返回值了,所以返回undefined
    
    //如果使用return方法,则返回值,并结束遍历
    
    obj.return('abc')  //{value:'abc', done: true} ,如果不传参,则返回undefined
    
    /**
        next方法也可以传参,next方法的参数表示上一个yield表达式的返回值,所以在第一次使用next方法时,
        传递参数是无效的。所以第一次调用无需传入参数
    **/
    
    function* gen(x) {
        let y = 1 + (yield (x + 1))
        let z = yield (y + 1)
        return x + y + z                         
    }
    
    const it = gen(5)
    
    console.log(it.next()) //{value: 6, done: false}
    
    console.log(it.next(9)) //{value: 11, done: false}
    console.log(it.next(2)) //{value: 17, done: true}
    /**
        解析一下上面的执行流程
        第一次执行,暂停返回x+1,也就是6。
        第二次执行,上次暂停的地方开始执行,传入的参数是9,也就是1+9,y=10,然后暂停返回10+1,也就是11
        第三次执行,还是从上次的地方开始,传入的是2,z=2return 5 + 10 + 2 ,也就是17
    **/
    
    //循环取值的方法
    
    function* gen() {
        yield 1
        yield 2
        return 3
    }
      
    for(let item of gen()) {
        console.log(item) // 1 2 ,done属性为true时,终止循环,并且不会返回值
    }
    
    

参考资料:www.cnblogs.com/rogerwu/p/1…