您的位置:首页 > 其它

ES6 —(Generator 函数应用)

2017-08-29 20:30 627 查看

(1)Generator 与状态机

  Generator 是实现状态机的最佳结构,每运行一次,就改变一次状态。Generator 之所以可以不用外部变量保存状态,是因为它本身就包含了一个状态信息,即目前是否处于暂停态。

var clock = function* (){
while(true){
console.log('Tick');
yield;
console.log('Tock');
yield;
}
}


(2)异步操作的同步化表达

  Generator 函数的暂停执行的效果,意味着可以把异步操作写在 yield 表达式里面,等到调用 next 方法时再往后执行。这实际上等同于不需要写回调函数,因为异步操作的后续操作可以放在 yield 表达式下面,反正要等到调用 next 方法时再执行。所以,Generator 函数的一个重要实际意义就是来处理异步操作,改写回调函数。

fnnction* numbers(){
let file = new FileReader("numbers.txt");
try{
while(!file.eof){
yield parseInt(file.readLine(), 10);
} finally {
file.close();
}
}
}


上面代码,打开文件,使用 yield 表达式可以手动逐行读取文件。

(3)控制流管理

  如果有一个多步操作非常耗时,采用回调函数,可能会写成下面这样:

step1( function(value1){
step2(value1, function(value2){
step3(value2, function(value3){
// 操作
});
});
});


  采用 Promise 改写上面的代码。

Promise.resolve(step1)
.then(step2)
.then(step3)
.then(function (value3){
// 操作
})
.done();


  使用 Generator 函数改写。

function* runningRask(value1){
try{
var value2 = yield step1(value1);
var value3 = yield step2(value2);
var value4 = yield step3(value3);
// 操作
} catch (e){}
}


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

let steps = [step1Func, step2Func, step3Func];
function* iterateSteps(steps){
for(var i = 0; i < steps.length; i++){
var step = step[i];
yield step();
}
}
for(var step of iterateSteps(steps)){}


注意:上面的做法只能用于所有步骤都是同步操作的情况,不能有异步操作的步骤。

(4)部署 Iterator 接口

  利用 Generator 函数,可以在任意对象上面部署 Iterator 接口。

function* iterEntries(obj) {
let keys = Object.keys(obj);
for (let i=0; i < keys.length; i++) {
let key = keys[i];
yield [key, obj[key]];
}
}

let myObj = { foo: 3, bar: 7 };

for (let [key, value] of iterEntries(myObj)) {
console.log(key, value);
}
// foo 3
// bar 7


(5)作为数组结构

  Generator 可以看作是数组结构,更确切地是,可以看作是一个数组结构,因为 Generator 函数可以返回一系列的值,这意味着它可以对任意表达式,提供类似数组的接口。

阮一峰:ECMAScript 6入门
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: