国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

koa源碼分析-co模塊以及thunk

caikeal / 2067人閱讀

摘要:以及模塊之前都是返回的函數(shù)之后的都是返回在語言中,函數(shù)替換的是將多參數(shù)函數(shù),替換成單參數(shù)的版本,且只接受回調(diào)函數(shù)作為參數(shù)。

Thunk以及CO模塊

co4.0之前都是返回的thunk函數(shù)
之后的都是返回promise

thunk

thunk:在 JavaScript 語言中,Thunk 函數(shù)替換的是將多參數(shù)函數(shù),替換成單參數(shù)的版本,且只接受回調(diào)函數(shù)作為參數(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); 
  };
};

生產(chǎn)環(huán)境中,可以使用thunkify將函數(shù)轉(zhuǎn)換為thunk 函數(shù)

問題:

為什么node 里面大部分的callback都是第一個(gè)參數(shù)是err呢?

為什么要做thunk 轉(zhuǎn)換呢?

在redux里面也有thunk middleware,這個(gè)thunk是什么意思呢?

CO 模塊

co的原理很簡(jiǎn)單,就是將傳入的generator function 轉(zhuǎn)換為一個(gè)thunk,并且轉(zhuǎn)換后thunk 的generator的每個(gè)value值作為下一個(gè)狀態(tài)的輸入

function co(fn) {

   var isGenFun = isGeneratorFunction(fn);

   return function (done) {//返回的thunk函數(shù),done 作為回調(diào)函數(shù)
        var ctx = this;
    
        // in toThunk() below we invoke co()
        // with a generator, so optimize for
        // this case
        var gen = fn;
    
        //gen function 轉(zhuǎn)換為generator
        if (isGenFun) {
          var args = slice.call(arguments), len = args.length;
          var hasCallback = len && "function" == typeof args[len - 1];
          done = hasCallback ? args.pop() : error;
          gen = fn.apply(this, args);
        } else {
          done = done || error;
        }
        //函數(shù)執(zhí)行的時(shí)候就會(huì)執(zhí)行next函數(shù),進(jìn)入函數(shù)體里面
        next();

        // #92
        // wrap the callback in a setImmediate
        // so that any of its errors aren"t caught by `co`
        function exit(err, res) {
          setImmediate(done.bind(ctx, err, res));
        }

        function next(err, res) {
          var ret;
    
          // multiple args
          if (arguments.length > 2) res = slice.call(arguments, 1);
    
          // error
          if (err) {
            try {
              ret = gen.throw(err);
            } catch (e) {
              return exit(e);
            }
          }
    
          // ok
          if (!err) {
            try {
              ret = gen.next(res);
            } catch (e) {
              return exit(e);
            }
          }
    
          // done
          if (ret.done) return exit(null, ret.value);
    
          // normalize
          ret.value = toThunk(ret.value, ctx);
    
          // run
          if ("function" == typeof ret.value) {
            var called = false;
            try {
            
              //比如執(zhí)行yield readFile("test.json"), ret.value就是readFile函數(shù),函數(shù)接受一個(gè)callback,callback調(diào)用next方法,講readFile的結(jié)果傳入了next函數(shù)
              ret.value.call(ctx, function(){
                //這里可以防止next函數(shù)被多次執(zhí)行
                if (called) return;
                called = true;
                next.apply(ctx, arguments);
              });
            } catch (e) {
              setImmediate(function(){
                if (called) return;
                called = true;
                next(e);
              });
            }
            return;
          }
    
          // invalid
          next(new Error("yield a function, promise, generator, array, or object"));
        }
      }
}

通過上面的co源碼分析,可以看下面的例子

co(function *() {
    var file = yield readFile("test.json");
    
    ?//這里的file是通過gen.next()?賦值的
    console.log(file);
    
    var ret = yield writeFile(file, "dest.json");
    
    console.log(ret);    
})

了解了這些基本概念后就可以進(jìn)入koa的源碼閱讀了,具體的可以參考下一篇。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/78882.html

相關(guān)文章

  • co模塊用法及分析

    摘要:模塊可以將異步解放成同步。源碼分析使用的模塊版本號(hào)為首先看一些用于判斷對(duì)象類型的函數(shù)對(duì)數(shù)組方法的引用這兩個(gè)應(yīng)該就不用說了吧。。。看一下模塊的輸出部分因此以下三種用法等價(jià)接著就是重頭戲函數(shù)了。 本文只在個(gè)人博客和 SegmentFault 社區(qū)個(gè)人專欄發(fā)表,轉(zhuǎn)載請(qǐng)注明出處 個(gè)人博客: https://zengxiaotao.github.io SegmentFault 個(gè)人專欄: h...

    muzhuyu 評(píng)論0 收藏0
  • 如何理解 koa 中間件執(zhí)行機(jī)制

    摘要:注是先前版本處理異步函數(shù)的方式,通過可以將異步函數(shù)封裝成,傳入普通參數(shù)后形成僅需要參數(shù)的偏函數(shù),以此簡(jiǎn)化調(diào)用代碼目前中的偏函數(shù)已經(jīng)被無情地化了。 前幾天研究了TJ的koa/co4.x和一系列koa依賴的源碼,在知乎上做出了人生首次回答(而且我真得再也不想去知乎回答技術(shù)問題了_(:з」∠)_),因此把文字搬到這里。 ES2015 Generator/Yield 關(guān)于Generator...

    charles_paul 評(píng)論0 收藏0
  • Koa / Co / Bluebird or Q / Generators / Promises /

    摘要:經(jīng)常游蕩在的我總能發(fā)現(xiàn)許多好問題和好答案。盡管網(wǎng)絡(luò)上有著各式各樣的關(guān)于該主題的指導(dǎo),但涉及到在各種情景下的最佳實(shí)踐,或者較好實(shí)踐的方面還是不夠清晰。我寄希望于針對(duì)我這篇裹腳布式問題的回復(fù)可以改變這一現(xiàn)狀。我感覺因此收益的絕對(duì)不止是我一個(gè)人。 經(jīng)常游蕩在 SO 的我總能發(fā)現(xiàn)許多好問題和好答案。它們的好不僅僅在于知識(shí)的價(jià)值,更可貴之處在于如何表達(dá):如何提問/如何回答。不久前我在 SF...

    xingpingz 評(píng)論0 收藏0
  • generator、co模塊和async三者的區(qū)別

    摘要:也就是說,函數(shù)的執(zhí)行,與普通函數(shù)一模一樣,只要一行。表示函數(shù)里有異步操作,表示緊跟在后面的表達(dá)式需要等待結(jié)果。函數(shù)庫(kù)約定,命令后面只能是函數(shù)或?qū)ο螅瘮?shù)的命令后面,可以跟對(duì)象和原始類型的值數(shù)值字符串和布爾值,但這時(shí)等同于同步操作。 generator 特點(diǎn) function* 可以使用yield返回多次 調(diào)用方法 使用next()執(zhí)行g(shù)enerator代碼,每次遇到y(tǒng)ield...

    lanffy 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<