成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Javascript中的Generator函數(shù)和yield關(guān)鍵字

ZHAO_ / 3212人閱讀

摘要:序在中,大家討論的最多的就是異步編程的操作,如何避免回調(diào)的多次嵌套。今天所講的和就是和異步編程有關(guān),可以幫助我們把異步編程同步化。然而這樣的方法依然需要依賴外在的庫函數(shù),于是中提出了和關(guān)鍵字。

在Javascript中,大家討論的最多的就是異步編程的操作,如何避免回調(diào)的多次嵌套。異步操作的回調(diào)一旦嵌套很多,不僅代碼會(huì)變的臃腫,還很容易出錯(cuò)。各種各樣的異步編程解決方案也被不斷提出,例如大家所熟知的Promise,co等等。今天所講的Generator和yield就是和異步編程有關(guān),可以幫助我們把異步編程同步化。

Generator簡介

Generator在形式上和函數(shù)差不多,只是在function和函數(shù)名之間多了一個(gè)*。Generator內(nèi)部必須使用yield關(guān)鍵字。例如:

function * gen(){
  var result1 = yield "hello";
  var result2 = yield "world";
  return result1 + result2;
}

當(dāng)調(diào)用Generator函數(shù)時(shí),并不會(huì)執(zhí)行函數(shù)內(nèi)部的代碼,而是返回一個(gè)遍歷器,該遍歷器包含一個(gè)next方法。每次執(zhí)行next方法,Generator函數(shù)體會(huì)開始執(zhí)行,直到遇到y(tǒng)ield語句,執(zhí)行該語句并在此暫停。用法如下:

var g = gen();
g.next(1);
//{value : "hello", done : false}
g.next(2);
//{value : "world", done : false}
g.next();
//{value : 3, done: true}
g.next();
//{value : undefined, done: true}

調(diào)用next方法會(huì)返回一個(gè)對象,這個(gè)對象包含兩個(gè)屬性,value和done,value即是當(dāng)前yield語句的值。done表示Generator函數(shù)體是否被執(zhí)行完。next方法同時(shí)接受一個(gè)參數(shù),這個(gè)參數(shù)會(huì)作為yield語句的返回值,可以被后面的程序所使用。當(dāng)程序執(zhí)行完或者遇到return語句,value即為函數(shù)體的返回值,done就變成了true。至此,如果再執(zhí)行next方法,value就為undefined, done依然是true。

Generator在遍歷中的應(yīng)用

在js中,我們要遍歷一個(gè)數(shù)組,我們可以用for...of這樣的語句來進(jìn)行遍歷,這其實(shí)也是因?yàn)閿?shù)組中包含了一個(gè)Generator遍歷器。如果我們的自己定義的對象也包含一個(gè)遍歷器,我們也就可以通過for...of等遍歷語句來遍歷自定義的對象。這個(gè)遍歷器被存在Symbol.iterator屬性中。

var myArray = {
  0: "你",
  1: "的",
  2: "名字",
  length: 3
};

myArray[Symbol.iterator] = function * (){
  for(var i = 0; i < this.length; i++) {
    yield this[i];
  }
};

for(var item of myArray) {
  console.log(item);
}
//你
//的
//名字
Generator在異步編程中的應(yīng)用

Javascript的核心就是異步編程,每個(gè)異步操作都會(huì)提供一個(gè)callback回調(diào)函數(shù)來返回執(zhí)行的結(jié)果。假設(shè)我們有幾個(gè)操作,后一個(gè)操作依賴前一個(gè)操作的結(jié)果,如果采用回調(diào)的方式:

step1(function(value1) {
  step2(value1, function(value2) {
    step3(value2, function(value3)) {
      //some code
    }
  });
})

這樣的代碼一單回調(diào)的嵌套變多,會(huì)讓程序變的非常難理解,同時(shí)也很容易出錯(cuò)。我們要做的就是將回調(diào)變的扁平化。Promise對象就是這樣的功能,將上述的操作Promise化:

step1().then(function(value1){
  return step2(value1);
}).then(function(value2){
  return step3(value2);
}).then(function(){
  //some code
})

我們可以看到嵌套變少了,但是這并不是最理想的解決方案,如果我們能將異步操作變成同步操作那樣,即沒了嵌套,程序也會(huì)變的好理解。Generator函數(shù)就給我們提供的這樣的機(jī)會(huì)。

function *workflow(){
  var value1 = yield step1();
  var value2 = yield step2();
  var value3 = yield step3();
  //some code
}

這樣就是我們希望結(jié)果,異步編程編程了同步編程的形式。我們接下來要做的是讓這個(gè)Generator執(zhí)行起來,所以我們需要一個(gè)執(zhí)行器。co就是一個(gè)執(zhí)行器,讓Generator自動(dòng)執(zhí)行。

co(function *workflow(){
  var value1 = yield step1();
  var value2 = yield step2();
  var value3 = yield step3();
  //some code
});

co有個(gè)限制,yield語句后面跟的只能是Promise對象或者Thunk函數(shù),關(guān)于co更詳細(xì)的介紹,可以參考阮老師的文章co 函數(shù)庫的含義和用法。然而這樣的方法依然需要依賴外在的庫函數(shù),于是ES6中提出了async和await關(guān)鍵字。async和await其實(shí)就是Generator的語法糖。只是它自帶執(zhí)行器。將上面的代碼改寫成async形式:

async function workflow(){
  var value1 = await step1();
  var value2 = await step2();
  var value3 = await step3();
  //some code
}

var result = workflow();

async沒有了co的限制。await關(guān)鍵字后面可以跟 Promise 對象和原始類型的值(數(shù)值、字符串和布爾值,但這時(shí)等同于同步操作)。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/88031.html

相關(guān)文章

  • JavaScript異步編程:Generator與Async

    摘要:從開始,就在引入新功能,來幫助更簡單的方法來處理異步編程,幫助我們遠(yuǎn)離回調(diào)地獄。而則是為了更簡潔的使用而提出的語法,相比這種的實(shí)現(xiàn)方式,更為專注,生來就是為了處理異步編程。 從Promise開始,JavaScript就在引入新功能,來幫助更簡單的方法來處理異步編程,幫助我們遠(yuǎn)離回調(diào)地獄。 Promise是下邊要講的Generator/yield與async/await的基礎(chǔ),希望你已...

    leon 評論0 收藏0
  • 《Node.js設(shè)計(jì)模式》基于ES2015+的回調(diào)控制流

    摘要:以下展示它是如何工作的函數(shù)使用構(gòu)造函數(shù)創(chuàng)建一個(gè)新的對象,并立即將其返回給調(diào)用者。在傳遞給構(gòu)造函數(shù)的函數(shù)中,我們確保傳遞給,這是一個(gè)特殊的回調(diào)函數(shù)。 本系列文章為《Node.js Design Patterns Second Edition》的原文翻譯和讀書筆記,在GitHub連載更新,同步翻譯版鏈接。 歡迎關(guān)注我的專欄,之后的博文將在專欄同步: Encounter的掘金專欄 知乎專欄...

    LiuRhoRamen 評論0 收藏0
  • JavaScriptGenerator理解使用

    摘要:返回的遍歷器對象,可以依次遍歷函數(shù)內(nèi)部的每一個(gè)狀態(tài)。下一步,必須調(diào)用遍歷器對象的方法,使得指針移向下一個(gè)狀態(tài)。從語義上講,第一個(gè)方法用來啟動(dòng)遍歷器對象,所以不用帶有參數(shù)。 Generator理解 Generator 函數(shù)是 ES6 提供的一種異步編程解決方案,可以這么理解: 從語法上,首先可以把它理解成,Generator 函數(shù)是一個(gè)狀態(tài)機(jī),封裝了多個(gè)內(nèi)部狀態(tài)。執(zhí)行 Generato...

    seal_de 評論0 收藏0
  • 異步流程控制:7 行代碼學(xué)會(huì) co 模塊

    摘要:而在中是迭代器生成器,被創(chuàng)造性的拿來做異步流程控制了。當(dāng)執(zhí)行的時(shí)候,并不執(zhí)行函數(shù)體,而是返回一個(gè)迭代器。行代碼再看看文章開頭的行代碼首先生成一個(gè)迭代器,然后執(zhí)行一遍,得到的是一個(gè)對象,里面再執(zhí)行。 廣告招人:阿里巴巴招前端,在這里你可以享受大公司的福利和技術(shù)體系,也有小團(tuán)隊(duì)的挑戰(zhàn)和成長空間。聯(lián)系: qingguang.meiqg at alibaba-inc.com 首先請?jiān)徫业臉?biāo)題...

    tinna 評論0 收藏0
  • ES6學(xué)習(xí)筆記之Generator函數(shù)

    摘要:調(diào)用函數(shù)后和普通函數(shù)不同的是,該函數(shù)并不立即執(zhí)行,也不返回函數(shù)執(zhí)行結(jié)果,而是返回一個(gè)指向內(nèi)部狀態(tài)的對象,也可以看作是一個(gè)遍歷器對象。第一個(gè)只是用來啟動(dòng)函數(shù)內(nèi)部的遍歷器,傳參也沒有多大意義。 之前斷斷續(xù)續(xù)接觸到了一些ES6的知識(shí),異步編程方面聽得比較多的就是Promise,直到最近比較系統(tǒng)地學(xué)習(xí)了ES6的新特性才發(fā)現(xiàn)Generator這個(gè)神奇的存在,它可以實(shí)現(xiàn)一些前所未有的事情,讓我頓時(shí)...

    cjie 評論0 收藏0

發(fā)表評論

0條評論

ZHAO_

|高級講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<