Generator 函数是协程在 ES6 的实现,最大特点就是可以交出函数的执行权(即暂停执行)。
function* gen(x){
var y = yield x+2
return y
}
var g = gen(1)
g.next() //{ value:3,done: false }
g.next() //{ value: undefined, done: true }
由于这个代码是可以暂停执行的,所以需要在函数名前面加个*号,其他地方跟普通函数没啥区别。
执行gen函数,会返回一个对象,对象中有一个next()函数,调用这个函数,会得到两个参数,value表示 yield 后面语句的值,done表示这个函数是否执行完毕。
我的理解就是:实际上 yield相当于一个标记点 这个函数被yield 分成了两个阶段,当调用next()的时候 ,函数就会运行到标记点的位置,并且返回标记点第一个阶段的状态(yield 后面语句的值,以及是否还有下一个阶段)。
next 方法返回值的 value 属性,是 Generator 函数向外输出数据;next 方法还可以接受参数,这是向 Generator 函数体内输入数据。
function* gen(x){
var y = yield x + 2;
return y;
}
var g = gen(1);
g.next() // { value: 3, done: false }
g.next(2) // { value: 2, done: true }
next() 可以接受一个参数,这个参数会被当成上一阶段的异步任务的返回结果被函数体内的变量y接受。所以g.next(2)输出的value是2。
Generator 函数内部还可以部署错误处理代码,捕获函数体外抛出的错误。
function* gen(x){
try {
var y = yield x + 2;
} catch (e){
console.log(e);
}
return y;
}
var g = gen(1);
g.next();
g.throw('出错了');
// 出错了
上面代码的最后一行,Generator 函数体外,使用指针对象的 throw 方法抛出的错误,可以被函数体内的 try ... catch 代码块捕获。
使用 Generator 函数,执行一个真实的异步任务。
var fetch = require('node-fetch'); //返回一个Promise对象
function* gen(){
var url = 'https://api.github.com/users/github';
var result = yield fetch(url);
console.log(result.bio);
}
var g = gen();
var result = g.next(); //得到的是 fetch(url)(Promise对象)
result.value.then(function(data){
return data.json();
}).then(function(data){
g.next(data);
});
网友评论