ES6 生成器

news/2025/2/26 7:34:16

基本概念

Generator函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同。

Generator函数有多种理解角度。从语法上,首先可以把它理解成,Generator函数是一个状态机,封装了多个内部状态。

执行Generator函数会返回一个遍历器对象,也就是说,Generator函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历Generator函数内部的每一个状态。

形式上,Generator函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield语句,定义不同的内部状态(yield语句在英语里的意思就是“产出”)。

function* helloWorldGenerator() {
  yield 'hello';
  yield 'world';
  return 'ending';
}

var hw = helloWorldGenerator();

上面代码定义了一个Generator函数helloWorldGenerator,它内部有两个yield语句“hello”和“world”,即该函数有三个状态:hello,world和return语句(结束执行)。

然后,Generator函数的调用方法与普通函数一样,也是在函数名后面加上一对圆括号。不同的是,调用Generator函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象,也就是上一章介绍的遍历器对象(Iterator Object)。

下一步,必须调用遍历器对象的next方法,使得指针移向下一个状态。也就是说,每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield语句(或return语句)为止。换言之,Generator函数是分段执行的,yield语句是暂停执行的标记,而next方法可以恢复执行。

hw.next()
// { value: 'hello', done: false }

hw.next()
// { value: 'world', done: false }

hw.next()
// { value: 'ending', done: true }

hw.next()
// { value: undefined, done: true }

上面代码一共调用了四次next方法。

第一次调用,Generator函数开始执行,直到遇到第一个yield语句为止。next方法返回一个对象,它的value属性就是当前yield语句的值hello,done属性的值false,表示遍历还没有结束。

第二次调用,Generator函数从上次yield语句停下的地方,一直执行到下一个yield语句。next方法返回的对象的value属性就是当前yield语句的值world,done属性的值false,表示遍历还没有结束。

第三次调用,Generator函数从上次yield语句停下的地方,一直执行到return语句(如果没有return语句,就执行到函数结束)。next方法返回的对象的value属性,就是紧跟在return语句后面的表达式的值(如果没有return语句,则value属性的值为undefined),done属性的值true,表示遍历已经结束。

第四次调用,此时Generator函数已经运行完毕,next方法返回对象的value属性为undefined,done属性为true。以后再调用next方法,返回的都是这个值。

总结一下,调用Generator函数,返回一个遍历器对象,代表Generator函数的内部指针。以后,每次调用遍历器对象的next方法,就会返回一个有着valuedone两个属性的对象。value属性表示当前的内部状态的值,是yield语句后面那个表达式的值;done属性是一个布尔值,表示是否遍历结束。

yield语句

由于Generator函数返回的遍历器对象,只有调用next方法才会遍历下一个内部状态,所以其实提供了一种可以暂停执行的函数。yield语句就是暂停标志。

遍历器对象的next方法的运行逻辑如下。

(1)遇到yield语句,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。

(2)下一次调用next方法时,再继续往下执行,直到遇到下一个yield语句。

(3)如果没有再遇到新的yield语句,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的对象的value属性值。

(4)如果该函数没有return语句,则返回的对象的value属性值为undefined

需要注意的是,yield语句后面的表达式,只有当调用next方法、内部指针指向该语句时才会执行,因此等于为JavaScript提供了手动的“惰性求值”(Lazy Evaluation)的语法功能。

异步调用

通过生成器每个2秒执行下一个函数

function one () {
			setTimeout( ()=>{
			console.log( "111" );inter.next()
			}, 2000)
			}
			function two () {
			setTimeout( ()=>{
			console.log( "222" );inter.next()
			}, 2000)
			}
			function three () {
			setTimeout( ()=>{
			console.log( "3333" );inter.next()
			}, 2000)
			}
			function*gen3( ) {
				yield one( );
				yield two( );
				yield three( );
			}
			let inter = gen3( );//启动请求
			inter.next();


http://www.niftyadmin.cn/n/233610.html

相关文章

IO多路转接—select,poll,epoll

目录 select 函数介绍 select基本工作流程 select的优缺点及适用场景 poll poll的优缺点 epoll epoll的相关系统调用 epoll_create epoll_ctl epoll_wait epoll工作原理 epoll服务器编写 epoll的优点 epoll工作方式 select 函数介绍 系统提供select函数来实现多路复…

Linux系统中curl命令用法

curl 是常用的命令行工具&#xff0c;用来请求 Web 服务器。它的名字就是客户端&#xff08;client&#xff09;的 URL 工具的意思。 常见参数&#xff1a; -A/--user-agent <string> 设置用户代理发送给服务器 -b/--cookie <namestring/file> c…

frp内网穿透——以连接到校园内网的服务器为例

有时候想摸鱼不去实验室&#xff0c;在宿舍就直接连接到实验室的GPU服务器。奈何服务器在校园网内部&#xff0c;外网无法直接直接访问。此时需要手动搭一个跳板机&#xff0c;来连接到内网的GPU服务器&#xff0c;这一过程怎么做到呢&#xff1f;我们可以使用frp内网穿透工具&…

Golang中是否可以无限开辟协程以及如何控制协程的数量?

文章目录1. Golang中是否可以无限开辟协程&#xff1f;2. 不控制goroutine数量引发的问题3. 如何控制goroutine的数量&#xff1f;⭐️3.1 只用有buffer的channel3.2 channel与sync同步组合方式3.3 利用无缓冲channel与任务发送/执行分离方式1. Golang中是否可以无限开辟协程&a…

ECShop开源商城与COS互通:降低本地存储负载、提升访问体验

ECShop简介 ECShop是一款开源电子商务平台&#xff0c;具有简单易用、安全稳定、模块化设计等特点。它提供了完整的电子商务解决方案&#xff0c;包括商品管理、订单管理、支付管理、配送管理、会员管理、促销管理、数据统计等功能。ECShop支持多语言、多货币、多种支付方式和配…

音频相关知识

目录 声音的本质 横波与纵波 为什么固体中既能传输横波&#xff0c;又能传输纵波&#xff0c;液体气体中只能传输纵波 声波 超声波与次声波 声音的三要素 音调 响度 音色 噪声 媒体音频 声道 分类 麦克风工作原理 模数转换 扬声器的使用原理 音频压缩类别 音…

第04讲:实战掌握 Byte Buddy,体验代码生成的顺畅

为什么需要运行时代码生成 我们知道&#xff0c;Java 是一种强类型的编程语言&#xff0c;即要求所有变量和对象都有一个确定的类型&#xff0c;如果在赋值操作中出现类型不兼容的情况&#xff0c;就会抛出异常。强类型检查在大多数情况下是可行的&#xff0c;然而在某些特殊场…

【JS运算】分组求和/平均值(reduce函数)

对于数组求和的问题&#xff0c;使用reduce函数能够最快的解决 如果你还不会reduce函数&#xff0c;可以看这一篇&#xff1a; reduce函数的使用 思路 reduce函数对相同group的值进行迭代求和 将分组的总和除以组里的个数得到平均值&#xff0c;然后存储起来 Sum函数&#x…