生成器(generator)

本文深入探讨了JavaScript中的生成器(generator)概念,详细解释了生成器函数的特性,如yield关键字的作用,如何通过next方法控制执行流程,以及如何处理错误和返回值。通过实例展示了生成器在迭代、组合多个生成器以及在控制流中的应用。同时,讨论了在生成器中调用其他生成器的两种方式及其效果。
摘要由CSDN通过智能技术生成

生成器(generator)

  • 生成器(generator)
  • generator
    • 生成器:由构造函数Generator创建的对象,该对象既是一个迭代器,同时又是一个可迭代对象(满足可迭代协议的对象)
    • 生成器函数的特点:
    1. 调用生成器函数,会返回一个生成器,而不是执行函数体(因为,生成器函数的函数体执行,受到生成器控制)

    2. 每当调用了生成器的next方法,生成器的函数体会从上一次yield的位置(或者开始位置)运行到下一个yield

      1. yield关键字只能在生成器内部使用,不可以在普通函数内部使用。
      2. yield表示暂停,并返回一个当前迭代的数据。
      3. 如果没有下一个yield,到了函数底部,这时done的值设为true。
    3. yield关键字后面的表达式返回的数据,会作为当前迭代的数据

    4. 生成器函数返回的值,会作为迭代结束时的value,但是,如果在迭代结束后,反复调用next函数,这时value的值为undefined。

    5. 生成器调用next的时候,可以传递参数,该参数会作为生成器函数体上一次yield表达式的值。
      -生成器函数第一次传参数没有任何意义

    6. 生成器带有一个throw方法,该方法于next的效果相同,唯一的区别在于
      -next方法传递的参数会被返回一个正常值
      -throw方法传递的参数是一个错误,会导致生成器函数内部发生一个错误

function* G2() {
            console.log("运行G2 - 开始")
            let result = yield "g1"
            console.log("运行G2 - 第一次")
            result = yield "g2"
            console.log("运行G2 - 第二次")
            return "g3"
        }

        function* createGenerator() {
            console.log("运行生成器 - 开始")
            let result = yield 1;//将1作为第一次迭代的值, result的值可以通过next方法的参数来改变,不传的话result的值为undefined
            console.log("运行生成器 - 第一次", result)
            result = yield 2;//将2作为第二次迭代的值
            console.log("运行生成器 - 第二次", result)
            result = yield* G2();//如果加入*号调用则进入新的生成器内部执行
            console.log("运行内部生成器 - 结束", result)
            result = yield 3;
            console.log("运行生成器 - 第三次", result)
            result = yield 4;
            console.log("结束", result)
        }
        const generator = createGenerator();//调用后一定得到一个生成器
        generator.next();
        generator.next(new Error("代码错误"));
        generator.next();
        结果:
        运行生成器 - 开始
		运行生成器 - 第一次 Error: 代码错误
		    at test.html:36
		运行生成器 - 第二次 undefined
		运行G2 - 开始

	const generator = createGenerator();//调用后一定得到一个生成器
        generator.throw(new Error("代码错误"));
        generator.next();
        generator.next();
        结果:
        Uncaught Error: 代码错误
    	at test.html:35
7. 生成器带有一个return方法,该方法会直接结束生成器函数
function* G2() {
            console.log("运行G2 - 开始")
            let result = yield "g1"
            console.log("运行G2 - 第一次")
            result = yield "g2"
            console.log("运行G2 - 第二次")
            return "g3"
        }

        function* createGenerator() {
            console.log("运行生成器 - 开始")
            let result = yield 1;//将1作为第一次迭代的值, result的值可以通过next方法的参数来改变,不传的话result的值为undefined
            console.log("运行生成器 - 第一次", result)
            result = yield 2;//将2作为第二次迭代的值
            console.log("运行生成器 - 第二次", result)
            result = yield* G2();//如果加入*号调用则进入新的生成器内部执行
            console.log("运行内部生成器 - 结束", result)
            result = yield 3;
            console.log("运行生成器 - 第三次", result)
            result = yield 4;
            console.log("结束", result)
        }
        const generator = createGenerator();//调用后一定得到一个生成器
        generator.next();
        generator.next();
        generator.return("aaaa");
        generator.next("aaaa");
        结果:
        运行生成器 - 开始
		运行生成器 - 第一次 undefined
function* createGenerator() {
            console.log("运行生成器 - 开始" )
            let result = yield 1;//将1作为第一次迭代的值, result的值可以通过next方法的参数来改变,不传的话result的值为undefined
            console.log("运行生成器 - 第一次", result)
            result = yield 2;//将2作为第二次迭代的值
            console.log("运行生成器 - 第二次", result)
            result = yield 3;
            console.log("运行生成器 - 第三次", result)
            result = yield 4;
            console.log("结束", result)
        }
        const generator = createGenerator();//调用后一定得到一个生成器
        console.log(generator.next())
        console.log(generator.next("a"))
        console.log(generator.next("b"))
        console.log(generator.next("c"))
        console.log(generator.next("d"))
        //结果
		运行生成器 - 开始
		{value: 1, done: false}
		运行生成器 - 第一次 a
		{value: 2, done: false}
		运行生成器 - 第二次 b
		{value: 3, done: false}
		运行生成器 - 第三次 c
		{value: 4, done: false}
		结束 d
		{value: undefined, done: true}
  1. 若需要在生成器内部调用其他生成器,注意:如果直接调用,得到的是一个生成器,如果加入*号调用则进入新的生成器内部执行,如果是yield *生成器函数()调用生成器函数,则该函数的返回结果,为该表达式的结果
 		function* G2() {
            console.log("运行G2 - 开始")
            let result = yield "g1"
            console.log("运行G2 - 第一次")
            result = yield "g2"
            console.log("运行G2 - 第二次")
            return "g3"
        }

        function* createGenerator() {
            console.log("运行生成器 - 开始")
            let result = yield 1;//将1作为第一次迭代的值, result的值可以通过next方法的参数来改变,不传的话result的值为undefined
            console.log("运行生成器 - 第一次", result)
            result = yield 2;//将2作为第二次迭代的值
            console.log("运行生成器 - 第二次", result)
            result = yield* G2();//如果加入*号调用则进入新的生成器内部执行
            console.log("运行内部生成器 - 结束", result)
            
            result = yield 3;
            console.log("运行生成器 - 第三次", result)
            result = yield 4;
            console.log("结束", result)
        }
        
        const generator = createGenerator();//调用后一定得到一个生成器
        for(let item of generator){
            console.log(item)
        }
        运行结果:
		运行生成器 - 开始
		1
		运行生成器 - 第一次 undefined
		2
		运行生成器 - 第二次 undefined
		运行G2 - 开始
		g1
		运行G2 - 第一次
		g2
		运行G2 - 第二次
		运行内部生成器 - 结束 g3
		3
		运行生成器 - 第三次 undefined
		4
		结束 undefined
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值