Generator函数异步应用

协程

协程的流程:协程A执行,执行到一半就将执行权转移给协程B,协程B交还执行权,然后A恢复执行。

如下所示:

function* asyncJob(){
    ...
    var f=yield readFile(fileA);//分界,执行到此处时会将执行权交给其它协程。
    ...
}

Generator函数是协程在ES6的实现,整个Generator函数就是一个封装的异步函数,任何需要异步操作暂停的地方,都要用yield来注明.

function* gen(x){
    var y=yield x+2;
    return y;
}
var g=gen(1);
g.next();
g.next();
//异步操作需要暂停的地方都要用yield注明

使用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}直接传进到上一步的异步操作中接收,被y接收
g.throw('出错')//在生成函数内部使用try...catch可以实现分离出错代码和处理错误的代码

使用Generator函数来封装异步操作:

var fetch=require('node-fetch');
function* gen(){
    var url='...';
    var result=yield fetch(url);
    console.log(result.bio);
}
var g=gen();
var result=g.next();//result是一个Promise对象。

Thunk函数

Thunk函数是自动执行Generator函数的一种方式,相当于传入表达式调用时求值,Thunk也是一种延迟求值的方法.

//传值调用和传名调用
//传值调用,在传入参数前先算出x+5的值。
f(x + 5)
//传名调用,传入表达式,传入后用到时再进行计算。
f(x+5)
(x+5)*2

Thunk函数将多参数函数替换为只接受回调函数作为参数的单参数函数。

//替换前
fs.readFile(fileName,callback);
//替换后
var Thunk=function(fileName){
    return function(callback){
        return fs.readFile(fileName,callback);
    }
    }
var readFileThunk=Thunk(fileName);
readFileThunk(callback);
function f(a,b,callback){
    var sum=a+b;
    callback(sum);
    callback(sum);
}
var ft=thunkify(f);
var print=console.log.bind(console);
ft(1,2)(print);

Thunk函数的自动流程管理

对于Generator函数来说,使用异步函数,配合Thunk函数可以实现不断回调自动执行。

function run(fn) {
  var gen = fn();
  function next(err, data) {
    var result = gen.next(data);
    if (result.done) return;
    result.value(next);
  }
  next();
}
var g = function* (){
  var f1 = yield readFileThunk('fileA');
  var f2 = yield readFileThunk('fileB');
  // ...
  var fn = yield readFileThunk('fileN');
};
run(g);

co模块

好难不会,就是说Promise和Thunk都能处理这种方式的异步调用吧

posted @ 2022-10-22 21:17  梦呓qwq  阅读(20)  评论(0编辑  收藏  举报