Generator函数与yield

ES6中的Generator函数与yield

generator函数是为了解决异步编程的函数,generator函数会返回一个可迭代对象(也就是可遍历的对象)。
形式上,Generator 函数声明方法和普通函数颇有相似之处,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)。

function* num() {
				yield "111";
				yield "222";
				yield "333";
			}
			const iterator = num();
			// console.log(iterator.next());
			// console.log(iterator.next());
			// console.log(iterator.next());
			// console.log(iterator.next());
			/*
        上述代码执行结果,generator函数是为了进行异步操作,而不会同步执行,
        代码内部被yield分隔,分隔的代码块为:yield的数量 + 1,generator函数并不会自己自动执行,而是需要调用next方法来执行
        调用next()方法会产生一个指针,第一个next()方法就执行第一个yield,当调用第二个yield时指针便会移动到第二个yield上,以此来遍历generator函数
        generator函数会返回一个迭代器对象,那么我们可以通过for of来进行遍历
        {value: '111', done: false}
        {value: '222', done: false}
        {value: '333', done: false}
        {value: undefined, done: true}
        */

			for (const v of iterator) {
				// console.log('遍历generator的每一项:',v);
			}
			/*
        上述代码遍历结果,所遍历的每一项都是调用next()n方法后所返回的对象中的value的值也就是yield后面的值
            遍历generator的每一项: 111
            遍历generator的每一项: 222
            遍历generator的每一项: 333
        */

			// 同样generator函数也和普通函数一样可以进行传参,同样next()方法也可以传参
			function* animal(args) {
				console.log("所接收到的参数:", ...args);
				yield "猴子";
				yield "大象";
				yield "海豹";
			}
			const animalGenerator = animal(["🐉", "🐍", "🐎", "🐏"]);
			// 如果只是单单调用generator函数,函数并不会进行执行,如果想要输出结果就必须要调用next()方法
			animalGenerator.next();

			// 对next()方法进行传参
			function* phone() {
				const res1 = yield "Huawei";
				console.log(res1);
				const res2 = yield "xiaomi";
				console.log(res2);
				const res3 = yield "oppo";
				console.log(res3);
			}
			const phoneSort = phone();
			phoneSort.next("aaa");
			phoneSort.next("bbb");
			phoneSort.next("ccc");
			phoneSort.next("ddd");
			/*
        上述代码执行结果:
        bbb
        ccc
        ddd
        可以发现我们给next()方法传参,传入了四个参数但是只打印了3个参数,这表明我们给next()方法进行传参的时候,传入的参数并不会被与之匹配的yield所接收
        而是成为了上一个yield的返回值,所以我们的res1并没有打印aaa而是打印的bbb
        */

			// 比较 yield与yield *
			function* generatorOne() {
				yield ["a", "b", "c"];
			}

			function* generatorTwo() {
				// yield* ["a", "b", "c"];
                yield 'a'
                yield 'b'
                yield 'c'
			}
            const one = generatorOne()
            const two = generatorTwo()
            console.log(one.next().value);
            console.log(two.next().value);
        /*
        使用yield* 的打印结果:
            ['a', 'b', 'c']
            a
        全部使用yield的打印结果:
            ['a', 'b', 'c']
            a
        可以发现两者打印结果一摸一样
        我们可以得出结论: yield* ['a','b','c']等价于 yield 'a'; yield 'b'; yield 'c';
        */ 


例题:

		 // 下面标注英文的位置应该输入什么样的代码,obj.next()才会是下面的内容
		 // 例题:
        const teams = [
            {name: 'Team 1', members: ['Paul', 'Lisa']},
            {name: 'Team 2', members: ['Laura', 'Tim']},
        ]
        // generator函数会返回一个可迭代对象
        function * getMembers(members) {
            for (let i = 0; i < members.length; i++) {
                yield members[i]
            }
        }
        function * getTeams(teams) {
            for (let i = 0; i< teams.length; i++) {
                // somthing is missing here    
          }
        }
        const obj = getTeams(teams)

       obj.next() // {value: "Paul", done: false}
       obj.next() // {value: "Lisa", done: false}
const teams = [
            {name: 'Team 1', members: ['Paul', 'Lisa']},
            {name: 'Team 2', members: ['Laura', 'Tim']},
        ]
        // generator函数会返回一个可迭代对象
        function * getMembers(members) {
            for (let i = 0; i < members.length; i++) {
                yield members[i]
            }
        }
        function * getTeams(teams) {
            for (let i = 0; i< teams.length; i++) {
                // somthing is missing here
                yield* getMembers(teams[i].members)
                // console.log(getMembers(teams[i].members));
                // let iterator = getMembers(teams[i].members)
                // 第一次循环所返回的可迭代对象相当于
                /*
                    yield 'Paul'
                    yield 'Lisa'
                */
                // 第二次循环所返回的可迭代对象相当于
                /*
                    yield 'Laura'
                    yield 'Tim'
                */
                // 所以 yield * getMembers(teams[i].members)相当于
                /*
                    yield * ['Paul', 'Lisa', 'Laura', 'Tim']
                */
                for (const v of iterator) {
                    // console.log(v);
                }
                // 判断这个循环执行了几次,是同步执行还是异步执行
                // console.log(i);
            }
        }
        const obj = getTeams(teams)
        // for of循环遍历一下generator对象:obj
        for (const item of obj) {
            console.log(item);
        }
        // obj.next() // {value: "Paul", done: false}
        // obj.next() // {value: "Lisa", done: false}

我们通过打印发现getMembers()函数每一次都会返回一个generator对象,里面的值正是teams中的members中的值,那么最后的值等价于

 yield * ['Paul', 'Lisa', 'Laura', 'Tim']
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值