在Node.js中使用Javascript Generators詳解_javascript技巧
Generators是Javascript的一種協同程式( coroutine 簡稱:協程)風格,是指那些可以在執行時暫停然後又恢復的函數,該函數是在functi配以星號符號形式如function* ,函數內有些特徵關鍵字如yield 和yield*。
function* generatorFn () { console.log('look ma I was suspended') } var generator = generatorFn() // [1] setTimeout(function () { generator.next() // [2] }, 2000)
對程式碼中標註的[1]和[2]解釋如下:
1. 這是一個generator以暫停方式開始. 這時沒有控制台輸出。
2.透過呼叫其next()方法,這個generator才會執行,運行直至它碰到下一個yield關鍵字或return,現在我們就有了控制台輸出。
再看一個案例:
function *generator() { console.log('Start!'); var i = 0; while (true) { if (i < 3) yield i++; } } var gen = generator();
以上這段程式碼類似第一個,只是在generator函數中多了yield關鍵字,以上這段程式碼被呼叫時,不會立即執行,而是暫停待命的狀態,因此不會有Start輸出。直到其next()呼叫才執行。
var ret = gen.next(); // Start! console.log(ret); // {value: 0, done: false}
上面ret是generator結果. 它有兩個屬性:
■value, 在generator函數的yield值,
■done, 這是一個標識表示generator函數是否回傳.
繼續程式碼如下:
console.log(gen.next()); // {value: 1, done: false} console.log(gen.next()); // {value: 2, done: false} console.log(gen.next()); // {value: undefined, done: true}
generator在同步編程中沒有什麼玄機,特別適合在非同步編程中。
generator有兩個特點:
1.能選擇跳出一個函數,讓外部程式碼決定什麼時候再跳回這個函數繼續執行。
2.能夠進行非同步控制。
看下面非同步執行程式碼:
var gen = generator(); console.log(gen.next().value); setTimeout(function() { console.log(gen.next().value); console.log('第一步'); }, 1000); console.log('第二步');
輸出是:
0
第二步
1
第一步
也就是說,不會在setTimeout這裡等待計時結束,而是直接繼續“第二步”,不會在setTimeout堵塞。
再看另外一段程式碼:
function* channel () { var name = yield 'hello, what is your name?' // [1] return 'well hi there ' + name } var gen = channel() console.log(gen.next().value) // hello, what is your name? [2] console.log(gen.next('billy')) // well hi there billy [3]
遍歷時也可以使用*:
function* iter () { for (var i = 0; i < 10; i++) yield i } for (var val of iter()) { console.log(val) // outputs 1?—?9 }
普遍的誤解
既然我可以暫停一個函數執行,那麼是不是讓它們並行執行呢?不是,因為Javascript是一個單線程,如果你想尋求提升效能,generator並不是你的菜。
例如下面程式碼分別執行斐波那契數:
function fib (n) { var current = 0, next = 1, swap for (var i = 0; i < n; i++) { swap = current, current = next next = swap + next } return current } function* fibGen (n) { var current = 0, next = 1, swap for (var i = 0; i < n; i++) { swap = current, current = next next = swap + next yield current } }
效能結果如下:(越高越好)
results:
regular 1263899
generator 37541
generators閃亮點
Generators 能簡化JavaScript中函數的複雜度。
懶賦值
懶賦值雖然可以使用JS的閉包實現,但是使用yield會有很大的簡化,透過暫停和恢復,我們能夠在我們需要的時候獲取數值,比如上面fibGen函數可以在我們需要時拉取新值:
var fibIter = fibGen(20) var next = fibIter.next() console.log(next.value) setTimeout(function () { var next = fibIter.next() console.log(next.value) },2000) 当然还使用for循环:依然是懒赋值 for (var n of fibGen(20) { console.log(n) }
無限序列
因為可以懶賦值,那麼可能表演一些Haskell招數, 類似infinite sequences. 這裡能夠yield一個無限序列的數量。
function* fibGen () { var current = 0, next = 1, swap while (true) { swap = current, current = next next = swap + next yield current } }
我們來看看一個斐波那契數流的懶賦值,要求它回傳5000以後的第一個斐波那契數:
for (var num of fibGen()) { if (num > 5000) break } console.log(num) // 6765
非同步流程控制
使用generators實現非同步流程控制,最常見是各種 promise庫包,那麼它是如何運作呢?
在Node領域,每個事情都和回呼有關,這是我們的低層次異步功能,我們可以使用generators 建立一個通訊通道,從而使用同步編程的風格編寫非同步程式碼。
run(function* () { console.log("Starting") var file = yield readFile("./async.js") // [1] console.log(file.toString()) })
註1表示程式會在等待async.js回傳結果以後再繼續。
genify是一個將generators帶入平常程式設計環境的框架,使用如下:
npm install genify 進行安裝,程式碼如下:
var Q = require('q'); var fs = require('fs'); var genify = require('genify'); // wrap your object into genify function var object = genify({ concatFiles: function * (file1, file2, outFile) { file1 = yield Q.nfcall(fs.readFile, file1); file2 = yield Q.nfcall(fs.readFile, file2); var concated = file1 + file2; yield Q.nfcall(fs.writeFile, outFile, concated); return concated; } }); // concatFiles是一个generator函数,它使用generator强大能力。 object.concatFiles('./somefile1.txt', './somefile2.txt', './concated.txt').then(function (res) { // do something with result }, function (err) { // do something with error });
以上這篇在Node.js中使用Javascript Generators詳解就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

用法:在JavaScript中,insertBefore()方法用於在DOM樹中插入一個新的節點。這個方法需要兩個參數:要插入的新節點和參考節點(即新節點將要插入的位置的節點)。

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

JavaScript是一種廣泛應用於Web開發的程式語言,而WebSocket則是一種用於即時通訊的網路協定。結合二者的強大功能,我們可以打造一個高效率的即時影像處理系統。本文將介紹如何利用JavaScript和WebSocket來實作這個系統,並提供具體的程式碼範例。首先,我們需要明確指出即時影像處理系統的需求和目標。假設我們有一個攝影機設備,可以擷取即時的影像數
