Generator函数

1,概念:

Generator函数有多种理解角度。从语法上,首先可以把它理解成,Generator函数一个状态机,封装了多个内部状态

执行Generator函数会返回一个遍历器对象,也就是说,Generator函数除了状态机,还是一个遍历器对象生成函数。

2,特征:

一是,function关键字与函数名之间有一个星号;

二是,函数体内部使用yield语句,定义不同的内部状态。(yield语句在英语里的意思就是“产出”)。

3,理解:

Generator函数的调用方法和普通函数一样,但不同的是,调用Generator函数后,该函数并不知晓,返回是也不是函数运行结果,而是一个指向内部状态的指针对象,也就是遍历器对象。 
必须调用遍历器对象的next方法,似的指针移动到下一个状态。也就是说,每次调用next方法,内部指针就从函数头部或上一次定下来的地方开始执行,直到遇到下一个yield语句(或return语句)为止。换言之,Generator函数是分段执行的,yield语句是暂停执行的标记,而next方法可以恢复执行。

4,总结:

调用Generator函数,返回一个遍历器对象,代表Generator函数的内部指针。以后每次调用遍历器对象的next方法,就会返回一个有着valuedone两个属性的对象。 
value属性表示当前的内部状态的值,是yield语句后面那个表达式的值;done属性是一个布尔值,表示是否遍历结束。

// 对象方法
//Generator 函数是协程在 ES6 的实现,最大特点就是可以交出函数的执行权(即暂停执行)。
const obj = {
    * n() {
        yield 'hello'
    }
}
console.log(obj.n().next());//{value: "hello", done: false}

// 函数
//整个 Generator 函数就是一个封装的异步任务,或者说是异步任务的容器。
//异步操作需要暂停的地方,都用 yield 语句注明。
function* stateFn(){
    yield '状态一';
    yield '状态二';
    return '状态三';
}
var state = stateFn();
console.log(state);//stateFn {<suspended>}
console.log(state.next());//{value: "状态一", done: false}
console.log(state.next());//{value: "状态二", done: false}
console.log(state.next());//{value: "状态三", done: true}
console.log(state.next());//{value: undefined, done: true}

//next 方法还可以接受参数,这是向 Generator 函数体内输入数据。
function* gen(x){
    var y = yield x +2;
    return y;
}
var g = gen(1);
console.log(g.next());//{value: 3, done: false}
//console.log(g.next());//{value: undefined, done: true}
//next 方法还可以接受参数
console.log(g.next(9));//{value: 9, done: true}

//Generator 函数内部还可以部署错误处理代码,捕获函数体外抛出的错误。
function* hen (x){
    try {
        var y = yield x + 4;
    }catch(e){
        console.log(e);//出错了
    }
}
var h = hen(1);
console.log(h.next());//{value: 5, done: false}
//这意味着,出错的代码与处理错误的代码,
//实现了时间和空间上的分离,这对于异步编程无疑是很重要的。
h.throw("出错了");
console.log(h.next());//{value: undefined, done: true}

 

posted @ 2017-12-28 17:44  最爱小虾  阅读(201)  评论(0编辑  收藏  举报