ES6學習--異步編程--Generator

異步編程 :

(異步編程的語法目的就是讓異步編程更像同步編程)

  1. 回調(diào)函數(shù)
    利用回調(diào)函數(shù)實現(xiàn)異步編程本身沒有問題, 問題在于回調(diào)函數(shù)的嵌套過多, 就會進入可怕的回調(diào)地獄.

  2. 事件監(jiān)聽

  3. 發(fā)布訂閱

  4. Promise
    是一種新的寫法,允許將回調(diào)函數(shù)的橫向加載,改成縱向加載, 但是代碼過長也會看起來語義不清晰

其實我覺得promise挺好了...大概是我太年輕

ES6異步編程:

協(xié)程: 多個線程互相協(xié)作,完成異步任務
第一步,協(xié)程A開始執(zhí)行。
第二步,協(xié)程A執(zhí)行到一半,進入暫停,執(zhí)行權轉(zhuǎn)移到協(xié)程B。
第三步,(一段時間后)協(xié)程B交還執(zhí)行權。
第四步,協(xié)程A恢復執(zhí)行。

Generator函數(shù)

Generator 函數(shù)就是協(xié)程在 ES6 的實現(xiàn),最大特點就是可以交出函數(shù)的執(zhí)行權(即暫停執(zhí)行)。

整個 Generator 函數(shù)就是一個封裝的異步任務,或者說是異步任務的容器。函數(shù)名之前要加星號, 異步操作需要暫停的地方,都用 yield 語句注明。

function* gen(x){
  var y = yield x + 2;
  return y;
}

Generator函數(shù)的執(zhí)行 :

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

上面代碼中,調(diào)用 Generator 函數(shù),會返回一個內(nèi)部指針g(即遍歷器) 。這是 Generator 函數(shù)不同于普通函數(shù)的另一個地方,即執(zhí)行它不會返回結(jié)果,返回的是指針對象。調(diào)用指針 g 的 next 方法,會移動內(nèi)部指針(即執(zhí)行異步任務的第一段),指向第一個遇到的 yield 語句,上例是執(zhí)行到 x + 2 為止。換言之,next 方法的作用是分階段執(zhí)行 Generator 函數(shù)。每次調(diào)用 next 方法,會返回一個對象,表示當前階段的信息( value 屬性和 done 屬性)。value 屬性是 yield 語句后面表達式的值,表示當前階段的值;done 屬性是一個布爾值,表示 Generator 函數(shù)是否執(zhí)行完畢,即是否還有下一個階段。

Generator 函數(shù)的數(shù)據(jù)交換和錯誤處理

Generator 函數(shù)可以暫停執(zhí)行和恢復執(zhí)行,這是它能封裝異步任務的根本原因。它還有兩個特性,使它可以作為異步編程的完整解決方案:函數(shù)體內(nèi)外的數(shù)據(jù)交換和錯誤處理機制。

next 方法返回值的 value 屬性,是 Generator 函數(shù)向外輸出數(shù)據(jù);next 方法還可以接受參數(shù),這是向 Generator 函數(shù)體內(nèi)輸入數(shù)據(jù)。

Generator 函數(shù)內(nèi)部還可以部署錯誤處理代碼,捕獲函數(shù)體外拋出的錯誤。

function* gen(x){
  try {
    var y = yield x + 2;
  } catch (e){ 
    console.log(e);
  }
  return y;
}

var g = gen(1);
g.next();
g.throw('出錯了');
// 出錯了

上面代碼的最后一行,Generator 函數(shù)體外,使用指針對象的 throw 方法拋出的錯誤,可以被函數(shù)體內(nèi)的 try ... catch 代碼塊捕獲。這意味著,出錯的代碼與處理錯誤的代碼,實現(xiàn)了時間和空間上的分離。

Generator 函數(shù)的用法

var fetch = require('node-fetch');

function* gen(){
  var url = 'https://api.github.com/users/github';
  var result = yield fetch(url);
  console.log(result.bio);
}

上面代碼中,Generator 函數(shù)封裝了一個異步操作,該操作先讀取一個遠程接口,然后從 JSON 格式的數(shù)據(jù)解析信息。就像前面說過的,這段代碼非常像同步操作,除了加上了 yield 命令。

var g = gen();
var result = g.next();

result.value.then(function(data){
  return data.json();
}).then(function(data){
  g.next(data);
});

首先執(zhí)行 Generator 函數(shù),獲取遍歷器對象,然后使用 next 方法,執(zhí)行異步任務的第一階段。由于Fetch 模塊返回的是一個 Promise 對象,因此要用 then 方法調(diào)用下一個next 方法。

參考自http://www.ruanyifeng.com/blog

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 簡介 基本概念 Generator函數(shù)是ES6提供的一種異步編程解決方案,語法行為與傳統(tǒng)函數(shù)完全不同。本章詳細介紹...
    呼呼哥閱讀 1,135評論 0 4
  • 在此處先列下本篇文章的主要內(nèi)容 簡介 next方法的參數(shù) for...of循環(huán) Generator.prototy...
    醉生夢死閱讀 1,486評論 3 8
  • 異步編程對JavaScript語言太重要。Javascript語言的執(zhí)行環(huán)境是“單線程”的,如果沒有異步編程,根本...
    呼呼哥閱讀 7,404評論 5 22
  • title標題: A Web Crawler With asyncio Coroutinesauthor作者: A...
    彰樂樂樂樂閱讀 2,207評論 0 8
  • 熊志軍~【日精進打卡第531天】 10月28號卡 付達新商貿(mào)~眾德營銷 沈陽盛和塾道盛組/稻芽七組 【知~學習】 ...
    熊志軍閱讀 168評論 0 0

友情鏈接更多精彩內(nèi)容