我们知道generator函数是es6引入的一种异步编程解决方案,那么问题就来了,我们前面知道promise对象也是用于解决异步问题的,那他们两个有什么区别呢?什么情况下应该用哪种方案呢?

普通函数与generator函数
首先我们知道普通的函数在执行的过程当中是一路走到底的,这就像是你坐飞机,在路上你不可能跟乘务长说停一下,你要下去,这是不可能的。但是generator函数可以,它中间能停!这就好比你坐出租车,中间你说你上楼拿个东西,让司机等你一下,是可行的。

什么时候暂停呢?
既然我们已经说到了在generator函数执行的过程当中,是可以暂停的,那么它到底什么时候暂停呢?这个时候就有了yield。

同时我们也会发现,当你创建一个genrator函数并且去执行它的时候,它是不会立即执行函数体内的东西的,而是创建了一个generator对象,这个对象当中有一个很重要的函数叫做next,
有了next这个函数,我们就可以在暂停之后继续执行下去。

function *show(){
			alert('a');
			yield;
			alert('b');
		}
		var gen  = show();
		console.log(gen);  //一个generator对象
		gen.next();
		gen.next();

从上面的解释当中我们其实可以看出,generator函数其实是有些像“揣一脚,走一步”的。

我们让这个函数暂停的原因,其实是因为我们需要去忙活一些事情,比如说我们去请求一些数据,这是一个异步操作,是需要花费时间的。需要让他等我们一下。

那么genrator函数是怎么实现走走停停的呢?
其实它的本质是用一个generator函数生成了很多个函数。

那么现在我们来看一些比较具体的例子:
yield它既可以用来返回中间结果,也能传参

function *show(){
			alert('a');
			let a = yield;
			alert('b');
			alert(a);  //5
		}
		var gen  = show();
		gen.next(12);
		gen.next(5);

为什么最后一次alert会输出5呢?我们可以这样看,其实yield就像是一堵墙,把函数分成了两个部分,执行第一个next的时候,是执行的yield之前的部分,而执行第二个next的时候,执行的其实是yield之后的部分,所以这个时候a是等于5的,就像下面这张图画的这样
generator
现在我们来看一下yield保存中间结果的情况


			function *show(){
				alert('a');
				yield 12;
				alert('b');
			}
			let gen = show();
			let res1  = gen.next();
			console.log(res1); //{value:12,done:false}
			let res2 = gen.next();

结果是如你所料的,value为12

那么现在我们可以更为清晰的用一张图来讲解yield保存中间结果的过程
generator如果我们想要在最开始的alert中打印出输入值,那么很明显我们可以在generator函数中加入参数,用来保存中间结果的是yield,而最终返回的“煮熟的菜”是通过return来返回的。

那么generator和promise到底什么时候用哪个呢?
如果你需要在异步操作之后进行逻辑判断去做一些事情,这时候如果异步操作多了,那么使用promise就会比较麻烦,而使用generator就会比较的简单,因为你只需要拿yield保存的值来做判断即可,这个写法就非常像是在写一个同步函数。

所以当在执行异步操作之后,需要夹杂复杂逻辑判断的时候用generator比较是比较好的选择,而你需要执行一堆异步操作,并且他们没有什么复杂逻辑判断的时候,使用promise是比较好的选择。

//图片来源于网络

相关文章:

  • 2021-04-29
  • 2021-04-09
  • 2021-11-10
  • 2021-09-02
  • 2021-10-24
  • 2022-02-02
猜你喜欢
  • 2022-12-23
  • 2021-07-09
  • 2021-09-02
  • 2021-08-18
相关资源
相似解决方案