社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
协程有点像函数,又有点像线程,它的运行流程大致如下。
Generator 函数是 ES6 对协程的实现,但属于不完全实现。Generator函数被称为“半协程”(semi-coroutine),意思是只有 Generator 函数的调用者,才能将程序的执行权还给 Generator函数。如果是完全执行的协程,任何函数都可以让暂停的协程继续执行。
Generator 函数执行产生的上下文环境,一旦遇到yield命令,就会暂时退出堆栈,但是并不消失,里面的所有变量和对象会冻结在当前状态。等到对它执行next命令时,这个上下文环境又会重新加入调用栈,冻结的变量和对象恢复执行。
function* gen() {
console.log(0);
yield;
console.log(1);
yield 'hello';
console.log(2);
console.log(yield);
yield* 'hello';
}
let f = gen();
f.next();//0
console.log(f.next().value);//1 hello
console.log(f.next('aaaaa').value);//2 undefined
console.log(f.next('world').value);//world h
console.log(f.next('').value);//e
console.log(f.next('').value);//l
console.log(f.next('').value);//l
console.log(f.next('').value);//o
console.log(f.next(''));//{value: undefined, done: true}
console.log(f.next(''));//{value: undefined, done: true}
执行generator函数之后,该函数并不会立即执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象。
每一次调用next()方法,内部指针就开始执行,直到遇到下一个yield表达式位置。(如果为yield*则会对其值进行for of处理)
next方法会返回此时yield的值。注意,yield本身所在行的代码,会在下一次yield才执行,包括next()方法内对yield的赋值。
即,next返回的值是下一个yield或return的值,而next传入的值会给上一个yield。
generator支持迭代器(Iterator),如
function* helloGenerator() {
yield "hello";
yield "generator";
return;
}
var h = helloGenerator();
for(var value of h){
console.log(value);//"hello","generator"
}
generator生成的对象,还有其他一些函数,比如throw()用来抛出错误,return()用来定义返回值并终止generator的状态。
以上的三个方法在本质上其实是一样的,他们就是让generator恢复执行,并且使用不同的语句来替代yield语句。
{value: undefined, done: true}
(此时的value为return的入参)//大厨的活
function* chef(){
console.log("fired chicken");//炒鸡
yield "worker";//交由伙计处理
console.log("sdd ingredients");//上料
yield "worker";//交由伙计处理
}
//伙计的活
function* worker(){
console.log("prepare chicken");//准备工作
yield "chef";//交由大厨处理
console.log("stewed chicken");
yield "chef";//交由大厨处理
console.log("serve chicken");//上菜
}
var ch = chef();
var wo = worker();
//流程控制
function run(gen){
var v = gen.next();
if(v.value =="chef"){
run(ch);
}else if(v.value =="worker"){
run(wo);
}
}
run(wo);//开始执行
//准备
function prepare(sucess){
setTimeout(function(){
console.log("prepare chicken");
sucess();
},500)
}
//炒鸡
function fired(sucess){
setTimeout(function(){
console.log("fired chicken");
sucess();
},500)
}
//炖鸡
function stewed(sucess){
setTimeout(function(){
console.log("stewed chicken");
sucess();
},500)
}
//上料
function sdd(sucess){
setTimeout(function(){
console.log("sdd chicken");
sucess();
},500)
}
//上菜
function serve(sucess){
setTimeout(function(){
console.log("serve chicken");
sucess();
},500)
}
//流程控制
function run(fn){
const gen = fn();
function next() {
const result = gen.next();
if (result.done) return;//结束
// result.value就是yield返回的值,是各个工序的函数
result.value(next);//next作为入参,即本工序成功后,执行下一工序
}
next();
};
//工序
function* task(){
yield prepare;
yield fired;
yield stewed;
yield sdd;
yield serve;
}
run(task);//开始执行
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!