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...