co原始碼分析 thunk版本3 1 0

2022-02-03 09:02:25 字數 3268 閱讀 2463

co的thunk版本,就是將所有 函式,generator,generator function,object,array,promise,都轉換為thunk函式,在thunk函式的**中,切換外部包裝的generator的狀態,即呼叫next方法,來依次執行所有的非同步任務。其中的,object和array,通過迴圈的方式,來並行執行thunk函式。

具體的原始碼注釋如下:

//

方便擷取函式引數

var slice =array.prototype.slice;

//匯出co函式

module.exports =co;

//wrap the given generator `fn` and return a thunk.

//包裹generator,並且返回乙個thunk函式,執行這個thunk函式,就可以開始整個非同步流程

//var thunk = co(function* ());

//開始執行 thunk();

function

co(fn)

else

//啟動執行,next會遞迴呼叫,直至所有非同步函式執行完畢

next();

//#92

//wrap the callback in a setimmediate

//so that any of its errors aren't caught by `co`

function

exit(err, res) );

}function

next(err, res)

catch

(e)

}//無錯誤,gen執行next,執行一次非同步函式,

if (!err)

catch

(e)

}//done為true,執行完所有非同步函式,退出

if (ret.done) return exit(null

, ret.value);

//把ret.value得到的函式轉換為thunk函式

ret.value =tothunk(ret.value, ctx);

轉換為thunk函式成功

if ('function' == typeof

ret.value) );

} catch

(e) );

}return

; }

轉換為thunk函式失敗,提示只能是以下型別

next(new typeerror('you may only yield a function, promise, generator, array, or object, '

+ 'but the following was passed: "' + string(ret.value) + '"'));}}}

//convert `obj` into a normalized thunk.

//將任何型別轉換為thunk

function

tothunk(obj, ctx)

//是generator,用co直接呼叫

if(isgenerator(obj))

//是promise,轉換為thunk函式

if(ispromise(obj))

//是函式,直接返回本身

if ('function' == typeof

obj)

//是物件或者陣列,轉換為thunk函式

if (isobject(obj) ||array.isarray(obj))

//都不是,直接返回物件,未成功轉換為thunk function,co的next函式會報錯,提示格式不符合

return

obj;}//

convert an object of yieldables to a thunk.

//將thunk陣列,或thunk物件,轉換為乙個thunk函式

//即將 arr = [thunk1,thunk2] 轉換為 乙個thunk

//或將 obj = 轉換為 乙個thunk

function

objecttothunk(obj));

return

; }

//prepopulate object keys to preserve key ordering

//物件型別,results按照obj的key,全部初始化為undefined

if (!isarray)

}//所有物件或陣列key對應的函式傳入run函式執行

for (var i = 0; i < keys.length; i++)

function

run(fn, key)

//fn是thunk函式,執行fn

fn.call(ctx, function

(err, res)

//在results中,用對應的key記錄fn執行結果,合法函式最終被記錄

results[key] =res;

//減小待處理數量,為0,就結束

--pending || done(null

, results);

});}

catch

(err) }}}

//promsie轉thunk

function

promisetothunk(promise) , fn);

}}//判斷是promise

function

ispromise(obj)

//generator function的返回值,就是乙個interator

function

isgenerator(obj)

//形如 function* () 都是 generator function

function

isgeneratorfunction(obj)

//判斷是物件

function

isobject(val) /**

* throw `err` in a new stack.

* * this is used when co() is invoked

* without supplying a callback, which

* should only be for demonstrational

* purposes.

* * @param err

* @api private */

function

error(err) );

}

co原始碼解讀

提取slice 函式方便使用 var slice array.prototype.slice 暴露 co module.exports co default co.co co 把generator函式 fn 包起來,返回promise this is a separate function so t...

Koa原始碼分析(二) co的實現

koa原始碼分析 一 generator koa原始碼分析 二 co的實現 koa原始碼分析 三 middleware機制的實現 大名鼎鼎的co是什麼?它是tj大神基於es6的一些新特性開發的非同步流程控制庫,基於它所開發的koa被視為未來主流的web框架。koa基於co實現,而co又是使用了es6...

通過原始碼理解thunk執行原理

1 函式的柯里化 函式返回函式返回函式 其實是乙個在連綴呼叫時不停收集變數和資料的過程,同時使用閉包將收集到的變數進行儲存。這麼做可以使函式由複雜的多入單出變成簡單的單入單出的狀態,同時也可以做到將引數進行復用和函式延遲執行的功能 2 redux的中介軟體的位置,位於資料傳入redux後,redux...