Node.js 生成器与回调函数对比
在本教程中,我们将学习生成器及其与回调函数的区别。
什么是生成器?
生成器在最近的 Node.js 中变得相当有名,这可能归因于它们的功能。
- 生成器是可以在稍后暂停和恢复的函数执行。
- 生成器在执行诸如“惰性求值”之类的概念时很有用。这基本上意味着通过暂停执行并根据需要恢复执行,我们可以仅在需要时拉取值。
生成器具有以下 2 个关键方法。
- Yield 方法 – Yield 方法在函数中使用,用于在调用 yield 方法的特定行暂停函数执行。
- Next 方法 – 此方法从主应用程序调用,用于恢复具有 yield 方法的函数的执行。函数执行将继续,直到下一个 yield 方法或直到函数末尾。
让我们看一个如何使用生成器的示例。
在我们的示例中,我们将有一个简单的 Add 函数来添加两个数字,但我们会不断地在不同的点暂停函数执行,以展示生成器如何使用。
function* Add(x) { yield x + 1; var y = yield(null); y = 6 return x + y; } var gen = Add(5); gen.next(); gen.next();
代码解释
- 第一步是定义我们的生成器“函数”。请注意,这是通过在 function 关键字后添加“*”来完成的。然后我们定义一个名为 Add 的函数,它接受一个 x 参数。
- Yield 关键字是生成器特有的。这使其成为在函数中间暂停的强大构造。因此,此时函数执行将暂停,直到我们调用 next() 函数,该函数将在第 4 步中完成。此时,x 的值将变为 6,函数执行将停止。
- 在这里,我们首次调用生成器函数并将 5 的值传递给我们的 Add 函数。此值将替换到我们 Add 函数的 x 参数中。
- 一旦我们调用 next() 函数,Add() 函数将恢复执行。当下一条语句 var y= yield(null) 执行时,Add() 函数将再次停止执行。
- 现在,再次调用 next() 函数后,将运行下一条语句,并将 x=5 和 y=6 的组合值相加并返回。
回调函数与生成器
生成器用于解决所谓的“回调地狱”问题。有时,在 Node.js 应用程序开发过程中,回调函数会变得如此嵌套,以至于使用回调函数变得非常复杂。
这就是生成器派上用场的地方。其中一个最常见的例子是创建计时器函数。
让我们看下面的示例,了解生成器如何比回调函数更有用。
我们的示例将创建一个简单的延迟函数。然后,我们希望调用此函数,并加入 1000、2000 和 3000 毫秒的延迟。
步骤 1) 定义带有必要延迟代码的回调函数。
function Timedelay(ptime, callback) { setTimeout(function() { callback("Pausing for " + ptime); }, time); }
代码解释
- 这里我们创建一个名为 Timedelay 的函数,它带有一个名为 ptime 的参数。这将接受我们在应用程序中引入的必要延迟。
- 下一步是创建一个消息,该消息将显示给用户,告知应用程序将暂停这么多毫秒。
步骤 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); }) }) })
代码解释
- 我们将 Timedelay 作为回调函数调用,值为 1000。
- 接下来,我们想再次调用 Timedelay 函数,值为 2000。
- 最后,我们想再次调用 Timedelay 函数,值为 3000。
从上面的代码可以看出,当我们开始多次调用函数时,它会变得更加混乱。
步骤 3) 现在让我们看看如何使用生成器来实现相同的代码。从下面的代码中,您现在可以看到使用生成器实现 Timedelay 函数变得多么简单。
function* Messages() { console,log(yield(Timedelay(1000, function(){}))); console,log(yield(Timedelay(2000, function(){}))); console,log(yield(Timedelay(3000, function(){}))); }
代码解释
- 我们首先定义一个将用于调用 Timedelay 函数的生成器函数。
- 我们将 Yield 函数与 Timedelay 函数一起调用,参数值为 1000。
- 然后,我们将 Yield 函数与 Timedelay 函数一起调用,参数值为 2000。
- 最后,我们将 Yield 函数与 Timedelay 函数一起调用,参数值为 3000。
摘要
生成器还可用于缓解嵌套回调的问题,并有助于消除所谓的“回调地狱”。生成器用于暂停函数的处理。这可以通过在异步函数中使用“yield”方法来完成。