国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > JS > 正文

在Node.js中使用Javascript Generators詳解

2024-05-06 16:30:45
字體:
供稿:網(wǎng)友
下面小編就為大家?guī)硪黄贜ode.js中使用Javascript Generators詳解。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考
 

Generators是Javascript的一種協(xié)同程序( coroutine 簡(jiǎn)稱:協(xié)程)風(fēng)格,是指那些可以在執(zhí)行時(shí)暫停然后又恢復(fù)的函數(shù),該函數(shù)是在functi配以星號(hào)符號(hào)形式如function* ,函數(shù)內(nèi)有些特征關(guān)鍵詞如yield 和yield*。

function* generatorFn () { console.log('look ma I was suspended')}var generator = generatorFn() // [1]setTimeout(function () { generator.next() // [2]}, 2000)

對(duì)代碼中標(biāo)注的[1]和[2]解釋如下:

1. 這是一個(gè)generator以暫停方式開始. 這時(shí)沒有控制臺(tái)輸出。

2.通過調(diào)用其next()方法,這個(gè)generator才會(huì)執(zhí)行,運(yùn)行直至它碰到下一個(gè)yield關(guān)鍵詞或return,現(xiàn)在我們就有了控制臺(tái)輸出。

再看一個(gè)案例:

function *generator() { console.log('Start!'); var i = 0; while (true) {  if (i < 3)   yield i++; }}var gen = generator();

以上這段代碼類似第一個(gè),只是在generator函數(shù)中多了yield關(guān)鍵詞,以上這段代碼被調(diào)用時(shí),不會(huì)立即執(zhí)行,而是暫停待命的狀態(tài),因此不會(huì)有Start輸出。直到其next()調(diào)用才執(zhí)行。

var ret = gen.next();// Start!console.log(ret);// {value: 0, done: false}

上面ret是generator結(jié)果. 它有兩個(gè)屬性:

■value, 在generator函數(shù)中的yield值,

■done, 這是一個(gè)標(biāo)識(shí)表示generator函數(shù)是否返回.

繼續(xù)代碼如下:

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在同步編程中沒有什么玄機(jī),特別適合在異步編程中。

generator有兩個(gè)特點(diǎn):

1.能選擇跳出一個(gè)函數(shù),讓外部代碼決定什么時(shí)候再跳回這個(gè)函數(shù)繼續(xù)執(zhí)行。
2.能夠進(jìn)行異步控制。

看下面異步執(zhí)行代碼:

var gen = generator();console.log(gen.next().value);setTimeout(function() { console.log(gen.next().value); console.log('第一步');}, 1000);console.log('第二步');

輸出是:

0
第二步
1
第一步

也就是說,不會(huì)在setTimeout這里等待計(jì)時(shí)結(jié)束,而是直接繼續(xù)“第二步”,不會(huì)在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]

在遍歷時(shí)也可以使用*:

function* iter () { for (var i = 0; i < 10; i++) yield i}for (var val of iter()) { console.log(val) // outputs 1?—?9}

普遍的誤解

既然我可以暫停一個(gè)函數(shù)執(zhí)行,那么是不是讓它們并行執(zhí)行呢?不是,因?yàn)镴avascript是一個(gè)單線程,如果你想尋求提升性能,generator并不是你的菜。

比如下面代碼分別執(zhí)行斐波那契數(shù):

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 }}

性能結(jié)果如下:(越高越好)

results: 
regular 1263899 
generator 37541

generators閃亮點(diǎn)

Generators 能簡(jiǎn)化JavaScript中函數(shù)的復(fù)雜性。

懶賦值

懶賦值雖然可以使用JS的閉包實(shí)現(xiàn),但是使用yield會(huì)有很大的簡(jiǎn)化,通過暫停和恢復(fù),我們能夠在我們需要的時(shí)候獲取數(shù)值,比如上面fibGen函數(shù)可以在我們需要時(shí)拉取新值:

var fibIter = fibGen(20)var next = fibIter.next()console.log(next.value)setTimeout(function () { var next = fibIter.next() console.log(next.value)},2000)當(dāng)然還使用for循環(huán):依然是懶賦值for (var n of fibGen(20) { console.log(n)}

無限序列

因?yàn)榭梢詰匈x值,那么可能表演一些Haskell招數(shù), 類似infinite sequences. 這里能夠yield一個(gè)無限序列的數(shù)量。

function* fibGen () { var current = 0, next = 1, swap while (true) {  swap = current, current = next  next = swap + next  yield current }}

我們看看一個(gè)斐波那契數(shù)流的懶賦值,要求它返回5000以后的第一個(gè)斐波那契數(shù):

for (var num of fibGen()) { if (num > 5000) break}console.log(num) // 6765

異步流程控制

使用generators實(shí)現(xiàn)異步流程控制,最常見是各種 promise庫(kù)包,那么它是如何工作呢?

在Node領(lǐng)域,每個(gè)事情都是和回調(diào)有關(guān),這是我們的低層次異步功能,我們可以使用generators 建立一個(gè)通訊通道,從而使用同步編程的風(fēng)格編寫異步代碼。

run(function* () { console.log("Starting") var file = yield readFile("./async.js") // [1] console.log(file.toString())})

注釋1表示程序會(huì)在等待async.js返回結(jié)果以后再繼續(xù)。

genify是一個(gè)將generators帶入平常編程環(huán)境的框架,使用如下:

npm install genify 進(jìn)行安裝,代碼如下:

var Q = require('q');var fs = require('fs');var genify = require('genify'); // wrap your object into genify functionvar 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是一個(gè)generator函數(shù),它使用generator強(qiáng)大能力。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詳解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持VeVb武林網(wǎng)。



注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到JavaScript/Ajax教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 讷河市| 临漳县| 永顺县| 新宁县| 桓仁| 大渡口区| 西宁市| 济阳县| 宜良县| 西安市| 泰宁县| 方正县| 屯留县| 耿马| 拜泉县| 榆树市| 搜索| 施秉县| 泰兴市| 若羌县| 新化县| 隆化县| 福建省| 九龙县| 荣昌县| 安阳市| 自贡市| 平度市| 马鞍山市| 汾阳市| 贵德县| 莱阳市| 宁津县| 当涂县| 南靖县| 株洲县| 修水县| 陕西省| 贞丰县| 濮阳县| 康平县|