爲何要實現generator和promise的結合呢?
大部分網上的文章都說是爲了更簡單的處理錯誤,不過這個我暫時尚未感悟,我反而以爲其實差很少;可是仍是先學習一下用法吧;
先從簡單的用法講起:promise
//最簡單的用法 function request() { return new Promise(function (resolve, reject) { setTimeout(function () { let num = Math.random(); if (num > 0.9) { reject(num + "request err") } else { resolve(num * 100); } }, 100) }) } let it = gen(); let p = it.next().value;// 在yield處被返回的Promise 被賦給了 p p.then(res => it.next(res).value, err => it.throw(err));// 發生錯誤時,將錯誤拋入生成器(gen)中 function* gen() { try { let response = yield request(); console.log(response.text); } catch (error) { console.log('Ooops, ', error.message); // 能夠捕獲Promise拋進來的錯誤!}} } }
這裏request的寫法就是普通的Promise異步的寫法,而gen中異步的寫法就已經很是像同步了,惟一一個缺點就是中間這一段代碼在咱們屢次異步的時候,咱們須要不斷的加長就像這樣dom
function request(){ //同上,我就不寫了 } let it = gen(); let p = it.next().value; //在res中返回了it.next(res).value,而這又是一個promise對象,這樣的話就能夠經過promise.then()的鏈式調用來寫了 p.then(res => it.next(res).value, err => it.throw(err)) .then(res => it.next(res).value, err => it.throw(err)); function* gen() { try { let response = yield request(); console.log(response); let response2 = yield request(); console.log(response,response2); } catch (error) { console.error('Ooops', error); // 能夠捕獲Promise拋進來的錯誤!}} } }
這樣就是否是很美了對吧,畢竟一直要寫重複的代碼。因此咱們再寫一個輔助generator自動跑的函數;異步
//generator 自動運行函數,可是要求改generator yield 後面跟的必須是promise對象 let genRun = function () { function run(p, gen) { p.then(resolve => { p = gen.next(resolve).value; if (p !== undefined) { run(p, gen) } }, reject => { p = gen.throw(reject).value; }) } return function (generator) { let g = generator(); run(g.next().value, g) } }(); function request() { return new Promise(function (resolve, reject) { setTimeout(function () { let num = Math.random(); if (num > 0.8) { reject(num + "request err") } else { resolve(num * 100); } }, 100) }) } genRun(function* () { try { let response1 = yield request(); console.log("response1", response1); let response2 = yield request(); console.log("response2", response2); let response3 = yield request(); console.log("response3", response3); } catch (e) { console.error(e) } });
這樣只要咱們保證request返回的是一個Primise
對象那麼咱們的異步代碼就能夠寫的異常的輕鬆了;函數
這一篇文章解釋的註釋很少,主要是由於這兩天太累了,之後有空再回來補輔助理解的註釋,還請各位看官老爺給個贊鼓勵一下,讓我有繼續寫下去的動力;oop