Node.js 生成器並與回撥進行比較
在本教程中,我們將瞭解生成器及其與回撥的不同之處
什麼是生成器?
最近,生成器在 Node.js 中已經非常有名,這可能是因為它們能夠做什麼。
- 生成器是函式執行,可以在以後暫停和恢復。
- 在執行諸如
lazy execution
之類的概念時,生成器非常有用。這基本上意味著通過暫停執行並隨意恢復,我們只能在需要時提取值。
生成器有以下兩種關鍵方法
yield
方法 - 在函式中呼叫 yield 方法,以在呼叫 yield 方法的特定行停止函式的執行。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();
程式碼說明: -
- 第一步是定義我們的生成器函式。請注意,這是通過在 function 關鍵字中新增
*
來完成的。然後我們定義一個名為 Add 的函式,它接受 x 的引數。 - yield 關鍵字是特定於生成器的。這使它成為在任何事物中間暫停函式的強大構造。所以在這裡,函式執行將停止,直到我們呼叫
next()
函式,這將在 Step4 中完成。此時,x 的值將變為 6,並且將停止執行該函式。 - 這是我們首先呼叫生成器函式並將值 5 傳送到 Add 函式的地方。該值將在 Add 函式的 x 引數中替換。
- 一旦我們呼叫
next()
函式,Add()
函式將恢復執行。當執行下一個語句 var y = yield(null)時,Add()
函式將再次停止執行。 - 現在再次呼叫
next()
函式後,將執行下一個語句,並且將新增並返回 x = 6 和 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。
- 接下來,我們要再次使用 2000 作為值來呼叫 Timedelay 函式。
- 最後,我們想再次使用 3000 作為值來呼叫 Timedelay 函式。
從上面的程式碼中,你可以看到它變得更加混亂,因為我們想要多次開始呼叫該函式。
步驟 3: 現在讓我們看看如何使用生成器實現相同的程式碼。從下面的程式碼中,你現在可以看到使用生成器實現 Timedelay 函式變得多麼簡單。
function* Messages() {
console.log(yield(Timedelay(1000, function(){})));
console.log(yield(Timedelay(2000, function(){})));
console.log(yield(Timedelay(2000, function(){})));
}
程式碼說明: -
- 我們首先定義一個生成器函式,用於呼叫我們的 Timedelay 函式。
- 我們呼叫 Yield 函式和 Timedelay 函式,並將 1000 作為引數值。
- 然後我們呼叫 Yield 函式和 Timedelay 函式,並將 2000 作為引數值。
- 最後,我們將 Yield 函式與 Timedelay 函式一起呼叫,並將 3000 作為引數值。
概要
生成器也可用於緩解巢狀回撥的問題,並有助於刪除所謂的回撥地獄。生成器用於停止函式的處理。這是通過在非同步函式中使用 yield
方法來實現的。