ES6 Generator
2017-10-18 16:54
162 查看
ES6 中规定, Generator 函数内部使用 this 无效,而且不能使用 new 关键字来获取 Generator 的一个实例。
这样,执行两次 next() 将 Generator 里面的数据执行完后,将 this 绑定到 a 的原型上面去。若还没有使用 next() 处理完 Generator 里面的数据,this 是不会绑定到 a.prototype 上去的。
ES6 之前,进行流程控制,我们大多数使用的是回调函数:
注意:
上面这种做法,只适合同步操作,即所有的task都必须是同步的,不能有异步操作。因为这里的代码一得到返回值,就继续往下执行,没有判断异步操作何时完成。
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都必须是同步的,不能有异步操作。因为这里的代码一得到返回值,就继续往下执行,没有判断异步操作何时完成。
相关文章推荐
- es6 用generator进行异步方法同步
- 使用es6 generator,报regeneratorRuntime is not defined 错误
- es6 Generator.prototype.return()方法
- ES6中Generator与异步操作实例分析
- ES6生成器函数generator
- co核心代码剖析--promise与ES6 generator结合
- ES6新特性:Generator以及衍生NPM库CO入门
- ES6中的迭代器(Iterator)和生成器(Generator)(一)
- ES6学习12章:Generator函数
- ES6(Generator)
- ES6(三) Generator (生成器)函数
- ES6新特性三: Generator(生成器)函数详解
- ES6中的迭代器(Iterator)和生成器(Generator)(二)
- 利用ES6的generator写一个时间间隔递增的定时器
- 02函数-05-generator(ES6)
- es6 Generator与异步的同步书写
- ES6--Generator
- ES6-深入理解Generator yield & Koa中间件执行顺序
- ES6 Generator
- es6 Generator (十五)