摘要:以及模塊之前都是返回的函數之后的都是返回在語言中,函數替換的是將多參數函數,替換成單參數的版本,且只接受回調函數作為參數。
Thunk以及CO模塊
co4.0之前都是返回的thunk函數
之后的都是返回promise
thunk:在 JavaScript 語言中,Thunk 函數替換的是將多參數函數,替換成單參數的版本,且只接受回調函數作為參數。
// 正常版本的readFile(多參數版本) fs.readFile(fileName, callback); // Thunk版本的readFile(單參數版本) var readFileThunk = Thunk(fileName); readFileThunk(callback); var Thunk = function (fileName){ return function (callback){ return fs.readFile(fileName, callback); }; };
生產環境中,可以使用thunkify將函數轉換為thunk 函數
問題:
為什么node 里面大部分的callback都是第一個參數是err呢?
為什么要做thunk 轉換呢?
在redux里面也有thunk middleware,這個thunk是什么意思呢?
CO 模塊co的原理很簡單,就是將傳入的generator function 轉換為一個thunk,并且轉換后thunk 的generator的每個value值作為下一個狀態的輸入
function co(fn) {
var isGenFun = isGeneratorFunction(fn); return function (done) {//返回的thunk函數,done 作為回調函數 var ctx = this; // in toThunk() below we invoke co() // with a generator, so optimize for // this case var gen = fn; //gen function 轉換為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; } //函數執行的時候就會執行next函數,進入函數體里面 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 { //比如執行yield readFile("test.json"), ret.value就是readFile函數,函數接受一個callback,callback調用next方法,講readFile的結果傳入了next函數 ret.value.call(ctx, function(){ //這里可以防止next函數被多次執行 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); })
了解了這些基本概念后就可以進入koa的源碼閱讀了,具體的可以參考下一篇。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/78882.html
摘要:注是先前版本處理異步函數的方式,通過可以將異步函數封裝成,傳入普通參數后形成僅需要參數的偏函數,以此簡化調用代碼目前中的偏函數已經被無情地化了。 前幾天研究了TJ的koa/co4.x和一系列koa依賴的源碼,在知乎上做出了人生首次回答(而且我真得再也不想去知乎回答技術問題了_(:з」∠)_),因此把文字搬到這里。 ES2015 Generator/Yield 關于Generator...
摘要:經常游蕩在的我總能發現許多好問題和好答案。盡管網絡上有著各式各樣的關于該主題的指導,但涉及到在各種情景下的最佳實踐,或者較好實踐的方面還是不夠清晰。我寄希望于針對我這篇裹腳布式問題的回復可以改變這一現狀。我感覺因此收益的絕對不止是我一個人。 經常游蕩在 SO 的我總能發現許多好問題和好答案。它們的好不僅僅在于知識的價值,更可貴之處在于如何表達:如何提問/如何回答。不久前我在 SF...
摘要:也就是說,函數的執行,與普通函數一模一樣,只要一行。表示函數里有異步操作,表示緊跟在后面的表達式需要等待結果。函數庫約定,命令后面只能是函數或對象,而函數的命令后面,可以跟對象和原始類型的值數值字符串和布爾值,但這時等同于同步操作。 generator 特點 function* 可以使用yield返回多次 調用方法 使用next()執行generator代碼,每次遇到yield...
閱讀 574·2021-11-18 10:02
閱讀 1057·2021-11-02 14:41
閱讀 684·2021-09-03 10:29
閱讀 1901·2021-08-23 09:42
閱讀 2737·2021-08-12 13:31
閱讀 1207·2019-08-30 15:54
閱讀 1960·2019-08-30 13:09
閱讀 1434·2019-08-30 10:55