Skip to content

14.Genrator 函数和应用

执行 Genrator 函数会返回一个遍历器对象,依次遍历 Genrator 内函数的每一个状态。特征: 1.function 关键字与函数名之间有个星号。2.函数体内使用 yield 表达式,定义不同状态。通过调用 next 方法将指针移向下一个状态,直到遇到下一个 yield 表达式(或 return)简单理解,Generator 函数分段执行,yield 表达式是暂时执行的标记而 next 执行回复。

function * f() {
    yield 'a';
    yield 'b';
    return 'ending';
}
let a = f();
a.next() // {value: 'a',done: false}
a.next() //{value: b,done:false}
a.next() //{value: 'ending',done: true}

14.1yield 表达式

yield 表达式是暂停标志,遍历器对象的 next 防封的运行逻辑如下:

  • 遇到 yield 就暂停执行,将这个 yield 后的表达式的值,作为返回对象的 value 属性值。
  • 下次调用 next 往下执行,直到遇到下一个 yield
  • 直到函数结束或者 return 为止并返回 return 语句后面表达式的值,作为返回对象的 value
  • 如果该函数没有 return 返回对象 value 为 undefined 注意 yield 只能在 generator 函数里面使用
(function(){
    yield 1 //syntax错误
})()

let a= [1,[2,3]]
let f = function * (i) {
    i.forEach(function(m){
        if(typeof m !=='number') {
            yield * f(m)
        }else{
            yield m
        }
    })
}

//yield 表达式如果用于另一个表达式必须在圆括号中
function * a() {
    console.log('a'+yield) //syn错误
    console.log('a'+yield 123) //syn错误
    console.log('a'+(yield)) //ok
}

14.2next 方法

yield 本生没有返回值或者总是返回 undefined,next 方法可带参数作为上一个 yield 表达式的返回值

function * f() {
    for(let k=0; true; k++) {
        let a = yield k;
        if(a) {
            k = -1
        }
    }
}
let g = f();
g.next()

14.3 控制流程

f1(function(v1){
    f2(function(v2){})
})

//Promise
Promise.resolve(f1).then(f2).then(f3)

//使用generator
function * f(v1) {
    try {
        let v2 = yield f1(v1);
        let v3 = yield f1(v2)
    }catch(err){

    }
}

14.4 异步编程使用

let fetch = require('node-fetch');
function * f() {
    let url = 'http://www.aa.com';
    let res  = yield fetch(url)
    console.log(res)
}
let g = f();
let result = g.next();
result.value.then(function(data){
    console.log(data)
})

15.class 语法和继承

15.1 介绍

ES6 中的 class 可以看作是一个语法糖,绝大部分功能都可以使用 ES5 来实现,情切类和模块的内部,是严格模式,所以不需要 use strict 指定运行模式

//es5
function P(x,y) {
    this.x = x;
    this.y = y;
}
P.prototype.toString = function(){
    return this.x+'-'+this.y;
}
var a = new P(1,2);

//es6
class P {
    constructor(x,y) {
        this.x = x;
        this.y = y;
    }
    toString() {
        return this.x+'-'+this.y;
    }
}
let a = new P(1,2)

注意 ES6 的方法其实是定义在原型上的

a.constructor = P.prototype.constructor

class 不存在遍历提升 Es6 中的类不存在变量提升,与 Es5 完全不同

new P{}
class P{}

class 的 name 属性

class P{}  
p.name //'P'

15.2constructor() 方法

  • constructor方法是类的默认方法,通过new实例化自动调用执行,一个类必须有constructor,否则会自动添加,方法返回实例对象
class P{}
//等同于
class P{
    constructor() {}
}