Node.js 生成器并与回调进行比较

在本教程中,我们将了解生成器及其与回调的不同之处

什么是生成器?

最近,生成器在 Node.js 中已经非常有名,这可能是因为它们能够做什么。

  • 生成器是函数执行,可以在以后暂停和恢复。
  • 在执行诸如 lazy execution 之类的概念时,生成器非常有用。这基本上意味着通过暂停执行并随意恢复,我们只能在需要时提取值。

生成器有以下两种关键方法

  1. yield 方法 - 在函数中调用 yield 方法,以在调用 yield 方法的特定行停止函数的执行。
  2. next 方法 - 从主应用程序调用此方法以恢复具有 yield 方法的函数的执行。函数的执行将持续到下一个 yield 方法或直到方法结束。

让我们看一下如何使用生成器的示例。

在我们的示例中,我们将有一个简单的 Add 函数,它将添加 2 个数字,但我们将继续停止在不同点的方法执行,以展示如何使用生成器。

function* Add(x) {
   yield x + 1;
   var y = yield(null);
   y = 6
   return x + y;
}
var gen = Add(5);
gen.next();
gen.next(); 

代码说明: -

  1. 第一步是定义我们的生成器函数。请注意,这是通过在 function 关键字中添加 * 来完成的。然后我们定义一个名为 Add 的函数,它接受 x 的参数。
  2. yield 关键字是特定于生成器的。这使它成为在任何事物中间暂停函数的强大构造。所以在这里,函数执行将停止,直到我们调用 next() 函数,这将在 Step4 中完成。此时,x 的值将变为 6,并且将停止执行该函数。
  3. 这是我们首先调用生成器函数并将值 5 发送到 Add 函数的地方。该值将在 Add 函数的 x 参数中替换。
  4. 一旦我们调用 next() 函数,Add() 函数将恢复执行。当执行下一个语句 var y = yield(null)时,Add() 函数将再次停止执行。
  5. 现在再次调用 next() 函数后,将运行下一个语句,并且将添加并返回 x = 6 和 y = 6 的组合值。

回调与生成器

生成器用于解决所谓的回调地狱的问题。有时回调函数在 Node.js 应用程序的开发过程中变得如此嵌套,以至于使用回调函数变得太复杂了。

这是生成器有用的地方。其中一个最常见的例子是创建计时器函数。

让我们看一下下面的例子,说明生成器如何证明对回调有用。

我们的例子只是创建一个简单的时间延迟函数。然后我们想要用这个函数来产生 1000,2000 和 3000 毫秒的延迟。

步骤 1: 使用必要的延时代码定义我们的回调函数。

	function Timedelay(ptime, callback) {

	setTimeout(function () {
		callback("Pausing for " + ptime);
	}, time);
}

代码说明: -

  1. 这里我们创建了一个名为 Timedelay 的函数,其函数名为 ptime。这将需要我们想要在我们的应用程序中引入的必要时间延迟。
  2. 下一步是创建一条消息,该消息将显示给用户,说明应用程序将暂停这么多毫秒。

步骤 2: 现在让我们看看代码,如果我们合并回调。假设我们想要基于 1000,2000 和 3000 毫秒的值来合并回调,下面的代码显示了我们如何使用回调来实现这些回调。

Timedelay(1000, function (message) {
	console.log(msg);
	Timedelay(2000, function (message) {
		console.log(msg); 
		Timedelay(3000, function (message) {
			console.log(msg);
		})
	})
})

代码说明: -

  1. 我们将 Timedelay 称为回调,其值为 1000。
  2. 接下来,我们要再次使用 2000 作为值来调用 Timedelay 函数。
  3. 最后,我们想再次使用 3000 作为值来调用 Timedelay 函数。

从上面的代码中,你可以看到它变得更加混乱,因为我们想要多次开始调用该函数。

步骤 3: 现在让我们看看如何使用生成器实现相同的代码。从下面的代码中,你现在可以看到使用生成器实现 Timedelay 函数变得多么简单。

function* Messages() {
	console.log(yield(Timedelay(1000, function(){})));
	console.log(yield(Timedelay(2000, function(){})));
	console.log(yield(Timedelay(2000, function(){})));
}

代码说明: -

  1. 我们首先定义一个生成器函数,用于调用我们的 Timedelay 函数。
  2. 我们调用 Yield 函数和 Timedelay 函数,并将 1000 作为参数值。
  3. 然后我们调用 Yield 函数和 Timedelay 函数,并将 2000 作为参数值。
  4. 最后,我们将 Yield 函数与 Timedelay 函数一起调用,并将 3000 作为参数值。

概要

生成器也可用于缓解嵌套回调的问题,并有助于删除所谓的回调地狱。生成器用于停止函数的处理。这是通过在异步函数中使用 yield 方法来实现的。