日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

異步編程之Generator(1)——領略魅力

系統 2414 0

異步編程系列教程:

  1. (翻譯)異步編程之Promise(1)——初見魅力
  2. 異步編程之Promise(2):探究原理
  3. 異步編程之Promise(3):拓展進階
  4. 異步編程之Generator(1)——領略魅力
  5. 異步編程之Generator(2)——剖析特性
  6. 異步編程之co——源碼分析

為何使用Generator


回顧一下我們之前學習的promise。我們巧妙利用了 promise/deferred 模式,用鏈式結構代替了嵌套回調的結構,大大緩解了回調地獄。我們再來看看之前我們舉的那個異步串行隊列的例子吧!假設我們有一個 hello.txt ,里面存了一個JSON文件的文件名,我們需要得到JSON文件的message屬性的值。步驟如下:

  1. 讀取 hello.txt 文件
  2. 得到JSON文件名,再次讀取文件
  3. 得到JSON數據后,進行JSON解析
  4. 獲得JSON的message屬性

Promise鏈式調用

這個例子我們之前也是舉過非常多次的,我們嘗試使用Promise鏈式結構完成:

    
      //這里的readFile已經是promise化的異步API
readFile('hello.txt', 'utf-8')
    .then(function(filename){
        return readFile(filename, 'utf-8');
    })
    .then(JSON.parse)
    .then(function(data){
        console.log(data.message);
    })
    .catch(function(err){
        console.error(err.message);
    });
    
  

這樣一看下來,promise好像并沒有多大問題,思維是線性的,而且錯誤處理也很友好。我們只需要把上一層執行后的結果通過 then() 傳到下一步執行即可。嗯,但不得不說被鏈式結構束縛后,我們并沒有得到一種酣暢淋漓的編程體驗。

同步API

我們要寫的爽,當然是要將異步編程得到同步編程的體驗,這樣我們直接使用同步API看一下是怎樣的:

    
      var filename = fs.readFileSync('hello.txt', 'utf-8');
var json = fs.readFileSync(filename, 'utf-8');
console.log(JSON.parse(json).message);
    
  

同步的寫法清晰明了,而且更符合我們以往的編程習慣。但是同步API阻塞代碼這個弊病會在Javascript的單線程執行中非常明顯。我們到底有沒有一種既可以非常接近同步編程的寫法,又可以異步不阻塞代碼執行呢?既然問出這種問題,答案當然是有的,就是今天的主角: Generator

Generator使用co寫法

Generator,顧名思義是一個構造器,它本身是用來生成迭代器的。它是ES6的新東西,所以你為了使用它,需要在node中開啟harmony模式才能體驗到它。

$ node --harmony

基于Generator,TJ大神做了一個 co 庫。 co 在最新的版本里,結合Generator和Promise改善了異步編程的體驗,也就是我們之前說的: 既可以同步,又不會阻塞

還是一樣的例子,我們結合promise的代碼和同步API的代碼對比看看:

    
      co(function* (){
    var filename = yield readFile('hello.txt', 'utf-8');
    var json = yield readFile(filename, 'utf-8');
    return JSON.parse(json).message;
}).then(console.log, console.error);
    
  

非常像有沒有,我們不再需要將每一次異步的結果都放在 then() 中進行處理,我們可以通過類似于同步的寫法調用Promise異步API,大大提升編程體驗。最后 co() 返回了一個promise對象,提供我們做最后的數據處理和錯誤處理。我們從同步API轉到 co ,僅僅需要做到以下幾點:

  • co里面傳的函數標識符需要加上*號, function* 。這也就是Generator函數
  • 調用promise異步API之前,都要加上 yield 標識符
  • 將需要做最后處理的數據 return 出來,在 then() 中進行處理即可

預習Generator


我們在舉完異步串行的例子后,這次的文章就接近尾聲了。最后我們可以大致了解一下 co 到底是如何運作的呢?我們會在接下來的文章進行深究,這一次就簡單說一說,你當作預習就可以了:

Generator相關

  1. Generator生成迭代器后,等待迭代器的 next() 指令啟動。
  2. 啟動迭代器后,代碼會運行到yield處停止。并返回一個 {value: AnyType, done: Boolean} 對象, value 是這次執行的結果, done 是迭代是否結束。并等待下一次的 next() 指令。
  3. next() 再次啟動后。若 done 屬性不為true,則可以繼續從上一次停止的地方繼續迭代。
  4. 一直重復2,3步驟,直到 done 為true。

co相關

  1. co內部的迭代器對象是被封裝成Promise的。
  2. yield 后面跟的必須是一個promise化的異步API,所以 next() 得到的結果是一個promise對象。
  3. 若迭代沒有結束,則 co 會自動為該異步promise對象的 resolve 中,增添一個 next() 。通過前面的異步執行完回調后,再調用 next() ,使迭代器的代碼不斷向前執行。
  4. 若迭代結束,則直接調用整個迭代器對象的 resolve

總結

或許現在大家看的是一知半解,或許很興奮想知道更多相關的。若僅僅是想學會用co,我想上面的大概已經足夠你看了。但是想更深入,你必須先弄懂promise的原理和Generator的相關特性。最后使用 co 庫一定會得心應手。

接下來,我會先講一些關于Generator的相關特性,再配合之前說過的promise,深入到 co 的源碼學習中。

異步編程之Generator(1)——領略魅力


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 鹤峰县| 依安县| 钦州市| 津市市| 长岛县| 贵溪市| 策勒县| 廊坊市| 泰顺县| 苍南县| 灵石县| 晋州市| 股票| 左贡县| 三亚市| 北海市| 南丹县| 织金县| 临沭县| 乌拉特前旗| 武鸣县| 崇阳县| 山东| 侯马市| 晴隆县| 松桃| 叙永县| 安庆市| 施秉县| 东丰县| 惠来县| 武隆县| 阳城县| 通州区| 虎林市| 利川市| 平和县| 清流县| 鱼台县| 沙洋县| 孝义市|