• ES6 generator 基础


    参考文档

    Generator是ES6的新特性,通过yield关键字,可以让函数的执行流挂起,那么便为改变执行流程提供了可能。

    创建Generator

    function * main() {
        var x = yield 1;
        var y = yield 2;
        var z = yield 3;
    }
    

    使用以上语法就可以声明一个generator,注意main是一个函数

    判断是否为generator

    function isGen(fn) {
        return 'function' === typeof fn && fn.constructor.name === 'GeneratorFunction';
    }
    

    generator的构造器

    main.constructor //function GeneratorFunction() { [native code] }
    

    Generator Object

    生成Generator Object

    var g= main();
    console.info(typeof g)
    

    g是Generator Object,在MDN上称为generator-iterator

    Generator Object方法

    next

    虽然main被调用了,但是并没有执行里面的方法体,而是返回了一个Generator Object,如何调用里面的方法体呢,这就要使用next方法

    console.log(g.next());//{value: 1, done: false}
    

    next方法在es6中定义如下

    The next function’s behavior is:

    1.If this is not a generator object, Throw Error

    2.Call this.[[Send]] with single argument undefined

    3.Return the result

    next方法会执行函数体,直到遇到第一个yield语句,然后挂起函数执行,等待后续调用。但是next会返回一个对象,这个对象有2个key,value表示yield语句后面的表达式的值('hello'),done是个布尔值,表示函数体是否已经执行结束。再次调用g。next时,执行流在挂起的地方继续执行,直到遇到第2个yield,依次类推。

    console.log(g.next());//{value: 2, done: false}
    console.log(g.next());//{value: 3, done: false}
    console.log(g.next());//{value: undefined, done: true}
    

    Tips:有时候我们把yield看成是return

    next方法也接受传参,传入参数作为yield语句的返回值;

    function *main() {
        var x = yield 1;
        console.log(x)
    }
    
    var g=main();
    g.next();
    g.next("hello world") //hello world
    

    next方法的特性很总要,很多基于generator做的流程控制都基于这个特性。

    异常处理

    function * main(){
        yield;a+b
    }
    
    var m=main()
    
    m.next()
    m.next()    //Uncaught ReferenceError: a is not defined
    

    我们可以使用catch捕获异常

    yield 和 yield*

    yield* 是委托提取器。yield 是你给什么它提取什么,但是 yield* 会继续向下请求,直到没的提取为止。

    function* a() { yield 1; yield 2; yield 3; }
    function* b() { yield 4; yield* a(); yield 5; }
    function* c() { yield 6; yield* b(); yield 7; }
    
    var cc = c();
    
    cc.next(); // {value: 6, done: false}
    cc.next(); // {value: 4, done: false}
    cc.next(); // {value: 1, done: false}
    cc.next(); // {value: 2, done: false}
    cc.next(); // {value: 3, done: false}
    cc.next(); // {value: 5, done: false}
    cc.next(); // {value: 7, done: false}
    cc.next(); // {value: undefined, done: true}
    

    DEMO

    function * G () {
        console.log(yield function () {
            console.log("func");
        });
    }
    
    var g = G();
    
    console.log(g.next());
    //{ value: [Function], done: false }
    console.log(g.next("hi"));
    //hi
    //{ value: undefined, done: true }
    

    支持情况

    • Chrome 35+ (about://flags中开启)
    • Firefox 31+ (默认开启)
    • nodejs harmony
  • 相关阅读:
    media query 开发总结
    整屏滚动
    移动端reset样式
    中国天气网 城市代码 sql语句
    php文章tag标签的增删
    oracle的分号和斜杠/
    php 操作 oracle lob 数据2
    php 操作 oracle lob 数据
    oracle创建用户
    php进度条
  • 原文地址:https://www.cnblogs.com/xiaoniuzai/p/6534417.html
Copyright © 2020-2023  润新知