ES6學(xué)習(xí)筆記——Generator函數(shù)的異步用法

什么是異步編程

異步編程可以理解為:一個任務(wù)A執(zhí)行到一半時间影,交出自己的執(zhí)行權(quán)并處于“暫吞哦В”狀態(tài)搀罢,轉(zhuǎn)而去執(zhí)行其他的任務(wù)(任務(wù)B)腋粥,然后再條件準(zhǔn)備好時晦雨,再回過頭來執(zhí)行任務(wù)A

在ES6之前,我們一搬會有以下幾種方法來實現(xiàn)異步編程:

  1. 回掉函數(shù)
  2. 事件監(jiān)聽
  3. 發(fā)布/訂閱
  4. Promise 對象(第三方庫)

但是在ES6時代隘冲,又多了一種異步編程的選擇—— Generator 函數(shù)

Generator 函數(shù)實現(xiàn)一個基本的異步編程

在上一篇中說過闹瞧,Generator 函數(shù)就像一個狀態(tài)機,調(diào)用后返回的遍歷器對象每調(diào)用一次 next() 方法展辞,遍歷器中的狀態(tài)指針才會向后移動到下一個狀態(tài)奥邮,并執(zhí)行下一個狀態(tài)之前的代碼,且不印象后面的代碼罗珍,這就為異步編程提供了良好的條件洽腺,使異步編程的書寫變得如同同步編程一般

function* generator() {
    console.log('start')
    var res = yield loop();
    console.log('end')
}

function loop() {
    console.time('loop');
    for (var i = 0; i < 1000000000; i ++) {}
    console.timeEnd('loop');
}

var g = generator();
g.next();
g.next();

// start
// loop: 540.537ms
// end

上面的代碼中,g 是 generator 方法返回的遍歷器對象覆旱。第一次調(diào)用 next() 方法時蘸朋,會先執(zhí)行 yield 之前的代碼 TASK A,然后執(zhí)行 yield 語句表達式 yield loop()扣唱,并執(zhí)行耗時函數(shù) loop

第二次調(diào)用 next() 方法時藕坯,會等待第一個 next() 方法完成再執(zhí)行 generator 方法內(nèi)后面的代碼

但是從上面的代碼可以看出,要想用 Generator 函數(shù)實現(xiàn)異步編程噪沙,需要手動地來控制狀態(tài)指針的后移炼彪,在實際工作中會不方便,所以就需要一個方法讓 Generator 函數(shù)能夠自動往后執(zhí)行

基于 Promise 對象自動執(zhí)行 Generator 函數(shù)

現(xiàn)將上面代碼改造成基于 Promise 對象的 Generator 函數(shù)

function* generator() {
    console.log('start')
    var res = yield loop();
    console.log('end')
}

function loop() {
    return new Promise(function(resolve, reject) {
        try {
            console.time('loop');
            for (var i = 0; i < 1000000000; i ++) {}
            console.timeEnd('loop');
        } catch (e) {
            reject(e);
        }
        resolve();
    })
}

var g = generator();
g.next().value.then(function() {
    g.next();
});

// start
// loop: 2576.482ms
// end

上面代碼中正歼, loop 方法被改造成一個返回 Promise 對象的方法辐马,這樣在調(diào)用第一個 next() 方法時,返回的對象的 value 熟悉就會使一個 Promise 對象局义,可以使用 then() 方法齐疙,再 then() 中再次調(diào)用 next() ,亦可以達到未改動之前的異步效果

基于以上改動后的代碼旭咽,將其最后執(zhí)行的方法封裝成可通用的代碼段

function run(generator){
  var g = generator();

  function next(data){
    var result = g.next(data);
    if (result.done) return result.value;
    result.value.then(function(data){
      next(data);
    });
  }

  next();
}

run(generator);

上面這段代碼中的 data 是需要傳遞的參數(shù),還記得在上一篇中所說的 next() 方法中參數(shù)的意義嗎赌厅?戳鏈接直達上一篇:

ES6學(xué)習(xí)筆記——Generator函數(shù)語法

需要注意的是穷绵,使用上面這段自動執(zhí)行代碼,yield 語句返回的 value 都必須是一個 Promise 對象特愿,否則是無法執(zhí)行的

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末仲墨,一起剝皮案震驚了整個濱河市勾缭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌目养,老刑警劉巖俩由,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異癌蚁,居然都是意外死亡幻梯,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門努释,熙熙樓的掌柜王于貴愁眉苦臉地迎上來碘梢,“玉大人,你說我怎么就攤上這事伐蒂∩饭” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵逸邦,是天一觀的道長恩沛。 經(jīng)常有香客問我,道長缕减,這世上最難降的妖魔是什么雷客? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮烛卧,結(jié)果婚禮上佛纫,老公的妹妹穿的比我還像新娘。我一直安慰自己总放,他們只是感情好呈宇,可當(dāng)我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著局雄,像睡著了一般甥啄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上炬搭,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天蜈漓,我揣著相機與錄音,去河邊找鬼宫盔。 笑死融虽,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的灼芭。 我是一名探鬼主播有额,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了巍佑?” 一聲冷哼從身側(cè)響起茴迁,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎萤衰,沒想到半個月后堕义,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡脆栋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年倦卖,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片筹吐。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡糖耸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出丘薛,到底是詐尸還是另有隱情嘉竟,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布洋侨,位于F島的核電站舍扰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏希坚。R本人自食惡果不足惜边苹,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望裁僧。 院中可真熱鬧个束,春花似錦、人聲如沸聊疲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽获洲。三九已至阱表,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間贡珊,已是汗流浹背最爬。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留门岔,地道東北人爱致。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像寒随,于是被迫代替她去往敵國和親蒜鸡。 傳聞我的和親對象是個殘疾皇子胯努,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 在此處先列下本篇文章的主要內(nèi)容 簡介 next方法的參數(shù) for...of循環(huán) Generator.prototy...
    醉生夢死閱讀 1,437評論 3 8
  • 異步編程對JavaScript語言太重要。Javascript語言的執(zhí)行環(huán)境是“單線程”的逢防,如果沒有異步編程,根本...
    呼呼哥閱讀 7,298評論 5 22
  • 簡介 基本概念 Generator函數(shù)是ES6提供的一種異步編程解決方案蒲讯,語法行為與傳統(tǒng)函數(shù)完全不同忘朝。本章詳細(xì)介紹...
    呼呼哥閱讀 1,068評論 0 4
  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持,譯者再次奉上一點點福利:阿里云產(chǎn)品券判帮,享受所有官網(wǎng)優(yōu)惠局嘁,并抽取幸運大...
    HetfieldJoe閱讀 6,373評論 9 19
  • 本文作者就是我,簡書的microkof晦墙。如果您覺得本文對您的工作有意義悦昵,產(chǎn)生了不可估量的價值,那么請您不吝打賞我晌畅,...
    microkof閱讀 23,720評論 16 78