co是干啥用的

再說co之前要先搞清楚 Thunk函數(shù)和 Generator函數(shù)

Generator函數(shù):
function* gen(x){
  var y = yield x + 2;
  return y;
}

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

簡單來說Generator 可以讓你擁有函數(shù)的控制權(quán)。上面代碼中g(shù)en函數(shù)返回一個(gè)對(duì)象,這個(gè)對(duì)象中有value 和dong 兩個(gè)值, value就是 函數(shù)中 yield 后面語句的值,而done 則用來判斷函數(shù)時(shí)候執(zhí)行完。你可以通過next()函數(shù)來執(zhí)行代碼,每次調(diào)用next 函數(shù)都會(huì)執(zhí)行到 yield 并且返回后面語句的值。

Thunk函數(shù):
// 正常版本的readFile(多參數(shù)版本)
fs.readFile(fileName, callback);

// Thunk版本的readFile(單參數(shù)版本)
var readFileThunk = Thunk(fileName);
readFileThunk(callback);

var Thunk = function (fileName){
  return function (callback){
    return fs.readFile(fileName, callback); 
  };
};

Thunk 可以讓你把一個(gè)接受多參數(shù)的函數(shù)(至少要用一個(gè)回調(diào)函數(shù)作為參數(shù))變成 接受單參數(shù)的函數(shù)。 上面代碼中先用 Thunk函數(shù) 固定來一個(gè)參數(shù) 然后返回一個(gè)函數(shù)。這樣,這個(gè)函數(shù)就只要接受一個(gè)回調(diào)作為參數(shù)。

Generator 跟 Thunk 配合使用 可以實(shí)現(xiàn) Generator 函數(shù)自動(dòng)執(zhí)行

co是干啥用的

co 可以幫你自動(dòng)執(zhí)行Generator

直接看源碼:

function co(gen) {
  var ctx = this;

  return new Promise(function(resolve, reject) {
    if (typeof gen === 'function') gen = gen.call(ctx);
    if (!gen || typeof gen.next !== 'function') return resolve(gen);

    onFulfilled();
    function onFulfilled(res) {
      var ret;
      try {
        ret = gen.next(res);
      } catch (e) {
        return reject(e);
      }
      next(ret);
    }    
  });
}

function next(ret) {
  if (ret.done) return resolve(ret.value);
  var value = toPromise.call(ctx, ret.value);
  if (value && isPromise(value)) return value.then(onFulfilled, onRejected);
  return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, '
        + 'but the following object was passed: "' + String(ret.value) + '"'));
    }
});

co 函數(shù)接受 Generator 函數(shù)作為參數(shù),返回一個(gè) Promise 對(duì)象。
然后 在Promise中 需要判斷一下 參數(shù)是不是Generator 函數(shù),如果是就執(zhí)行這個(gè)函數(shù)。這樣就會(huì)得到一個(gè)新的對(duì)象,你可以通過這個(gè)對(duì)象的next 控制Generator 函數(shù)的執(zhí)行,如果不是就返回,并將 Promise 對(duì)象的狀態(tài)改為 resolved 。

onFulfilled 函數(shù)會(huì)調(diào)用上面返回的對(duì)象的next函數(shù)讓Generator 函數(shù)進(jìn)行下一步, onFulfilled 函數(shù)中用來try...catch 來捕獲錯(cuò)誤。

最后會(huì)執(zhí)行next(ret) 這里的ret 是把上一階段處理完畢的異步結(jié)果傳入next函數(shù)。

next函數(shù)先通過參數(shù)中的done 來判斷是否是Generator 函數(shù)的最后一步,如果是就返回。
然后給了確保 參數(shù)是Promise對(duì)象 把參數(shù)轉(zhuǎn)換為Promise對(duì)象
使用then 傳入兩個(gè)回調(diào) 如果成功 就調(diào)用onFulfilled (調(diào)用自身)
如果失敗 拋出一個(gè)錯(cuò)誤,并且終止執(zhí)行。

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

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

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