Generator 函数是 ES6 提供的一种异步编程解决方案(异步编程方式有:回调函数 、事件监听、 发布/订阅者 、 Promise对象)。语法上,可以把理解成,Generator 函数是一个状态机,封装了多个内部状态。
定义Gernerator函数
function*test(){
yield 'hello'
yield 'word'
return 'ok';
}
var temp = test()
console.log(temp) //Generator {_invoke: ƒ} 一个指向内部状态的指针对象
console.log(temp.next()) //{value: "hello", done: false}
console.log(temp.next()) //{value: "word", done: false}
console.log(temp.next()) //{value: "ok", done: true}
console.log(temp.next()) //{value: undefined, done: true}
注意: 调用Generator函数后,函数并不执行,返回的也不是函数执行后的结果,而是一个指向内部状态的指针对象,每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止。有暂停执行的效果,这样就可以把异步操作写在yield语句里面,等到调用next方法时再往后执行。这实际上等同于不需要写回调函数了
看一个例子:
有三个操作fun1,fun2,fun3,现在想先执行fun1,然后将执行fun1之后得到的值value1作为参数传入fun2,再将执行fun2之后得到的结果value2作为参数执行fun3
传统回调的方式
fun1(function (value1) {
fun2(value1, function(value2) {
fun3(value2, function(value3) {
console.log(value3)
});
});
});
Promise方法改写可以这么写(假设fun1,fun2,fun3已经是三个Promise对象)
fun1().then(function(value1) {
return fun2(value1);
}).then(function(value2){
return fun3(value2);
}) .then(function(value3) {
console.log(value3)
});
Generator函数写法
function* do(value1) {
try {
var value2 = yield fun1(value1);
var value3 = yield fun2(value2);
var value4 = yield fun3(value3);
} catch (e) {
console.log(e)
}
}
函数一次执行:
function act(task) {
var obj= task.next(task.value);
if (!obj.done) {
task.value = obj.value
act(task);
}
}
act(do(value));