异步编程中对Generator和thunk函数的认识

什么是Generator 如何定义

Generator 是一个带星号的“函数”(它并不是真正的函数,下面的代码会为你验证),可以配合 yield 关键字来暂停或者执行函数。

function* gen() {

  console.log("enter");

  let a = yield 1;

  let b = yield (function () {return 2})();

  return 3;

}

var g = gen()           // 阻塞住,不会执行任何语句

console.log(g.next())

console.log(g.next())

console.log(g.next())

console.log(g.next()) 

// output:

// { value: 1, done: false }

// { value: 2, done: false }

// { value: 3, done: true }

// { value: undefined, done: true }

是怎么工作的

  • 生成器不一定会执行生成器函数体,通过创建迭代器对象,可以与生成器通信
  • 迭代器用于控制生成器的执行。迭代对象暴露的最基本接口是next方法迭,这方法可以用来向生成器请求一个值, 从而控制生成器
  • next函数调用后,生成器就开始执行代码,当代码执行到yield关键字时,就会生成一个中间结果(生成值序列中的一项),然后返回一一个**新对象,**其电封装了结果健一个指示完成的指示器。
    在这里插入图片描述
  • 每当生成一个当前值后,生成器就会非阻塞地挂起执行,随后耐心等待下一次值滑求的到达。这是普通函数完全不具有的强大特性,后续的例子中它还会起到更大的作用。

Generator的内部构成

我们已经知道了调用一个生 成器不会实际执行它。相反,它创建了一一个新的迭代器,通过该迭代器我们才能从生成器中请求值在生成器生成(或让渡)了一个值后,生成器会挂起执行并等待下一一个请求的到来。在某种方面来说,生成器的工作更像是一个小 程序,一个在状态中运 动的状态机。

  • 挂起开始创建了一个生成器后,它最先以这种状态开始。其中的任何代码都未执行。

  • 执行生成器中的代码执行的状态。执行要么是刚开始,要么是从上次挂起的时候继续的。当生成器对应的迭代器调用了next方法,并且当前存在可执行的代码时,生成器都会转移到这个状态,

  • 挂起让渡——当生成器在执行过程中遇到了一个yield表达式,它会创建一个包含着返回值的新对象,随后再挂起执行。生成器在这个状态暂停并等待继续执行。

  • 完成——在生成器执行期间,如果代码执行到return 语句或者全部代码执行完毕,生成器就进入该状态。
    在这里插入图片描述

与生成器的交互

  1. 作为生成器函数参数发送值
  2. 使用next方法向生成器发送值

在这里插入图片描述

在这里插入图片描述

yield基本介绍

yield 同样也是 ES6 的新关键词,配合 Generator 执行以及暂停。yield 关键词最后返回一个迭代器对象,该对象有 value 和 done 两个属性,其中 done 属性代表返回值以及是否完成。yield 配合着 Generator,再同时使用 next 方法,可以主动控制 Generator 执行进度。

什么是thunk函数

thunk函数的作用非常简单 其实就是把一个函数的 执行参数 和 回调分成两个函数(可以把函数本身也进行包装) 只要是有回调函数的 就可以用thunk进行包装

thunk定义

fn(args, callback)--->变成--->thunk(fn)(args)(callback)

Generator和thunk如何结合

因为thunk的执行函数和回调函数是分开的,会造成

  1. 代码逻辑里面上面来说不符合常规逻辑
  2. 回调函数里面嵌套逻辑处理太多的话,那thunk的优势就没了
执行函数执行-->等待回调函数传回数据-->用户对于获取的数据进行操作
  1. 把所有的执行函数放入generator函数里面,利用generator函数的yield对执行函数的流程控制
  2. 把函数执行权移出函数到对应的回调函数,获取数据后再把数据返回来
  3. 等到下次再遇到next()函数,函数执行权又回到生成器

在这里插入图片描述

var fs = require('fs');
var thunkify = require('thunkify');
var readFile = thunkify(fs.readFile);

//发现执行参数的函数在一起
var gen = function* () {
	var data1 = yield readFile('./a.txt');
	//用户获取数据后自定义写在这里
	console.log(data1.toString());
	var data2 = yield readFile('./b.txt');
		//用户获取数据后自定义写在这里
	console.log(data2.toString());
}


//写个执行函数
//发现callback在一起  而且调用的形式都一样
var g = gen();
//var d1 = g.next();

//执行value 实际为执行总函数 -->回调函数
// d1.value(function(err, data) {
// 	if (err) throw err;
// 	//传回数据
// 	var d2 = g.next(data);
// 	d2.value(function(err, data2) {
// 		if (err) throw err;
// 		g.next(data2);
// 	});
// });
//下面是利用thunk对函数进行总结书写
function run(gen){

  const next = (err, data) => {

    let res = gen.next(data);

    if(res.done) return;

    res.value(next);

  }

  next();

}


run(g)

在这里插入图片描述
参考

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值