美文网首页
generator异步调用原理

generator异步调用原理

作者: Aleph_Zheng | 来源:发表于2020-02-17 23:08 被阅读0次

generator是一个状态保存机,每次遇到yield会停止,需要调用next函数来执行

function * test1(){
  yield 3+2
  console.log('a')
  yield 7
  return 5
}
let t = test1()
t.next()//{value:5,done:false}
t.next()//a,{value:7,done:false}
t.next()//{value:5,done:true}

而yield返回的值是无法直接捕捉到的

function * test1(){
  let a = 8+(yield 3+2)
  console.log(a)
}
let t = test()
t.next()//{value:5,done:false}
t.next()//NaN,{value:undefined,done:true}

因为yield不会赋值给左边a,永远等于undefined,8+undefined就返回NaN了,
而在next函数中传值可以等于赋值给上一个yield的结果

function * test1(){
  let a = 8+(yield 3+2)
  console.log(a)
}
let t = test()
t.next()//{value:5,done:false}
t.next(6)//14,{value:undefined,done:true}

这一次我们第二次给next传值6,则a = 8 + 6 =14,我们没写return,默认return为undefined,所以value为undefined

thunk函数

thunk函数起源于函数的求值方式

function add(a,b)
变成
addThunk(a)(b)

一个readFile的thunk可以这么写

var Thunk = function (fn) {
    return function (...args) {
        return function (callback) {
            return fn.call(this, ...args, callback)
        }
    }
}

var readFileThunk = Thunk(fs.readFile)
readFileThunk('./1.txt')(function(err,data){})

这是一种惰性求值方式,但是结合generator却很好地控制流程,原因是可以把函数和它的回调抽离出来,如果我们在把回调抽象成一个函数,集中处理这个next指针,那么写法就和同步代码无异了

这样的话,next指针在上一个函数的回调里执行,因此只有上一个异步调用返回以后才会继续往下执行。

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('./1.txt');
    console.log(f1.toString());
    var f2 = yield readFileThunk('./2.txt');
    console.log(f2.toString());
    var fn = yield readFileThunk('./3.txt');
};

run(g);

上面的next函数,实际就是我们抽离出来控制next指针的

第一次执行,调用run函数,传入g函数,执行后返回gen
调用next(),err和data均为undefined,此时result为{value:function readFileThunk('./1.txt'),done:false}

然后再调用result.value(next),就把next函数继续放入回调中


第二次:
readFileThunk('./1.txt')返回结果,此时调用上一步的回调函数next,传入err和data,在gen.next传入data,那么上一步返回的结果就为data,因此f1就为读取1.txt的结果,它通过在下一次回调中,把结果通过gen.next传回去实现的。

基本就是这种方式实现异步控制的,关键就是控制权的处理上

相关文章

  • generator异步调用原理

    generator是一个状态保存机,每次遇到yield会停止,需要调用next函数来执行 而yield返回的值是无...

  • [js异步编程]封装Generator的co函数

    我们使用ES7的语法 async await可以将异步函数来同步调用。 其实原理是利用了ES6的Generator...

  • Generator(生成器)函数

    基本概念## 解决 异步编程,整个 Generator 函数就是一个封装的异步任务,或者说是异步任务的容器。 调用...

  • Generator函数

    Generator 函数是 ES6 提供的一种异步编程解决方案。调用 Generator 函数后,该函数并不执行,...

  • redux-saga学习笔记

    1.Generator函数 Generator函数时ES6提供的一种异步编程解决方案,函数调用后,函数并不执行,返...

  • dubbo原理

    1、RPC原理 一次完整的RPC调用流程(同步调用,异步另说)如下: 2、netty通信原理 Netty是一个异步...

  • 异步执行原理简要总结

    异步http调用,线程池调用简要原理 主线程封装一个FutureTask给异步框架, 异步框架有管理类管理主线程传...

  • JavaScript异步Thunk

    在Generator一文中最后的例子,自动执行异步操作,还不够“自动”,毕竟每次调用异步API时,还需要手动指定r...

  • Generator生成器函数

    管理异步流程递归 function co (generator) {const g = generator()fu...

  • generator

    面试题 将类数组转化成数组 用generator 异步读取数据,也得通过返回promise,层层调用。 解决方式,...

网友评论

      本文标题:generator异步调用原理

      本文链接:https://www.haomeiwen.com/subject/hatwfhtx.html