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 方法來實現的。