ES6 Generator

ES6 中规定, Generator 函数内部使用 this 无效,而且不能使用 new 关键字来获取 Generator 的一个实例。

1、内部使用 this

如下方法可以使得 Generator 内部的 this 关键字有效:

function* a() {
    this.a = 1;
    yield "hello";
    yield "world"
};

let b = a();
console.log(b.a, b.next(), b.next());
//undefined { value: 'hello', done: false } { value: 'world', done: false }

let c = a.call(a.prototype);
console.log( c.next(), c.next(), c.a)
//{ value: 'hello', done: false } { value: 'world', done: false } 1

这样,执行两次 next() 将 Generator 里面的数据执行完后,将 this 绑定到 a 的原型上面去。若还没有使用 next() 处理完 Generator 里面的数据,this 是不会绑定到 a.prototype 上去的。

2、状态机

Generator 是实现状态机的最佳结构,比如如下代码:

var clock = function* () {
    while (true) {
        console.log('Tick!');
        yield;
        console.log('Tock!');
        yield;
    }
};
let a = clock();
a.next(); //Tick!
a.next(); //Tock!
a.next(); //Tick!
a.next(); //Tock!
a.next(); //Tick!

let b = clock();
b.next(); //Tick!
b.next(); //Tock!
a.next(); //Tock!
3、控制流管理

利用for…of循环会自动依次执行yield命令的特性,提供一种更一般的控制流管理的方法。

ES6 之前,进行流程控制,我们大多数使用的是回调函数:

function step1(val, fun) {
    console.log("step" + val++);
    if (typeof fun == "function") fun(val);
    return val;
}
function step2(val, fun) {
    console.log("step" + val++);
    if (typeof fun == "function") fun(val);
    return val;
}
function step3(val, fun) {
    console.log("step" + val++);
    if (typeof fun == "function") fun(val);
    return val;
}
function step4(val, fun) {
    console.log("step" + val++);
    if (typeof fun == "function") fun(val);
    return val;
}
//原本流程控制需要使用回调函数的方式来实现,如下:
function task(init) {
    step1(init, function (val1) {
        step2(val1, function (val2) {
            step3(val2, function (val3) {
                step4(val3, function (val4) {
                    //......
                })
            })
        })
    });
}
task(1);

//采用 Promise 改写上面的代码:
Promise.resolve(step1(1))
    .then(val => step2(val))
    .then(val => step3(val))
    .then(val => step4(val));

//Generator 函数实现上面代码逻辑
function* rangeTask(initVal) {
    try {
        let val1 = yield step1(initVal);
        let val2 = yield step2(val1);
        let val3 = yield step3(val2);
        let val4 = yield step4(val3);
        //...
    } catch (e) {
        console.log(e)
    }
}

function scheduler(task) {
    let obj = task.next(task.value);
    if (!obj.done) {
        task.value = obj.value;
        scheduler(task);
    }
}

scheduler(rangeTask(1));

注意:
上面这种做法,只适合同步操作,即所有的task都必须是同步的,不能有异步操作。因为这里的代码一得到返回值,就继续往下执行,没有判断异步操作何时完成。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值