如何評價 Node.js 的koa框架?
koa2 完全拋棄了generator和co的做法,而是使用async/await來做非同步開發。
## 不同
1. koa和express在表現上的一點不同是採用ctx一個參數來調用中間件,而不是express的req, res。其實在使用上還是個人認為是更方便了的。2. 然後是在中間件連接的方式上有所不同。
express的設計是串聯的,設計思路超級簡潔。koa的某一個中間件可以自行選擇之後中間件的執行位置的。## 舉例
比如一個伺服器處理時間/日誌的中間件的開發:express:request進來,記錄時間到request._startTime上。綁定一個函數到response的"end","finish"以及response.socket的"error","close"事件上。那個函數會用當前時間和startTime做差,算出運行時間。koa2:```jsconst xTime = async (ctx,next)=&>{ let start = new Dateawait next()
ctx.set("X-Response-Time", (new Date) - start) + "ms")}```這是在功能開發上,在錯誤處理上的友好度就更高了。沒有特意抹黑express的中間件開發,那個express版的計時器是express自帶的伺服器日誌中間件morgan的實現。## 社區
express的社區還是大。koa本來就小,還被從koa1轉koa2一折騰,就更小了。而現在koa2還在alpha版,koa及其插件的開發速度比較沒有保證。你找到一個中間件,如果是express的,得轉過來。如果是koa的,一般也得再轉一次。
比如我使用的passportjs,github有koa版koa-passport,就分koa1版本和koa2版本的,選擇時得注意一下。## 個人評價
koa2好用,設計上的確有優勢。優勢不在能實現更強的功能,而是可以更簡單地完成功能。koa2社區遠不如express,原因之一是~~因為koa2的正式版離發行估計還得3~6個月。~~koa的正式版是koa1。koa1在思想上與koa2是一致的,但是koa2的實現更漂亮。有koa1到koa2的中間件封裝函數`koa-convert`。而一般通用的中間件都有koa版,或者能夠輕鬆的轉為koa版。個人收集的koa2中間件集合[@wusisu/koa-middlewares](https://www.npmjs.com/package/@wusisu/koa-middlewares),在公司項目使用中沒啥問題,開發需求暫時都足以實現。
有足夠折騰能力的team推薦使用koa。
-------updated 20160708
聽說koa組表示async被納入es7準則前,不會發布kao2的正式版。並且,似乎有koa3出現的跡象。只是我不知道該怎麼打入他們組織里了解詳情。給你方便的 yield 還不用,這叫賤。還什麼「非同步思維」,工具是解決問題,不是增加問題的。我看好它。
一句話評價:koa可以用yield讓你的代碼更加清晰可讀。老生常談了:代碼是寫給人看的,順便讓機器執行而已。
不作死就不會死。
generator 的產生本省並不是為了解決非同步的問題,visionmedia/co · GitHub 基於 generator 創建了一個把非同步編程同步書寫的模式,注意其實還是非同步的。但是這個模式實際代碼執行時還是非同步的。
而koa則是在此基礎上構建起來的。koa依賴於co的模式,不過之前大量的express的中間件都不能直接在koa上使用,為了實現co的模式這些中間件可能需要重寫,或者需要通過thunk等工具來做模式轉換。
koa比起express另一特點是:express讓請求逐個通過中間件,實現處理網路請求,而koa加上了中間件的回溯,即先逐個通過中間件再反穿回來。這個模式是基於co構建的,不基於co其實也可以構建這個模式,但是這個模式真的有那麼有用么?比express好多少?
co的同步寫法加上koa穿來穿去的模式,我覺得比起express複雜了很多,但並沒有解決express解決不了的問題。
一家之言,其實我沒怎麼用過koa,甚至是express,期待大家踴躍討論!Node.js 社區中大家基於 coroutine (yield+Promise) 的編程方式肯定會稱為今後兩三年的主流。那麼顯然 koa 這種基於 coroutine (co) 的框架會逐漸替代 Express。事實上,koa 的中間件已經發展起來了。
設計上 Koa 通過把一個中間件中的所有非同步操作都 yield 出去,用 co 包來處理,剩下的都是同步的代碼。
好處是一層中間件可以從傳進來和傳出去兩個方向都得到調用的機會。
這點很實用,因為一般情況下,一層一層回調下去,中間件基本上沒有機會有第二次機會得到調用。(有一些通過,request 的 end 事件來處理,終究是不美觀)。可以在第二次時候做一些掃尾的工作,或者是解鎖之類的,並且也不複雜。另外,可以通過 try catch 做異常處理,不用擔心非同步問題了。
壞處很明顯,就是 需要 把函數轉為 co 指定的幾種格式,開銷上來說有點大。
但是放眼未來,ES6 內置 Promise,如果 Promise 廣泛支持了的話,開發 KOA 就會變得很輕鬆。
將來函數可能會變成這個樣子
Model.find(params,[callback] )
傳參:
params: 查詢條件
callback(Optional): 回調函數
返回:
Promise
自從玩了yield,非同步和同步各種穿插,隨心所欲,讓人第一次對js這門語言充滿了信心,不黑它了。
為什麼沒人說koa主要解決的是回調金字塔的問題?
還沒有用,打算搭一個小型本地的APIweb代理。想試試。
看了官網的例子,最直觀的感覺就是省了個中間件。
偽代碼
要輸出 132
express 中間件1{console.log("1")next()}中間件2{console.log("3")next()}中間件3{console.log("2")next()}koa
中間件1{console.log("1")next 中間件2console.log("2")}
中間件2{console.log("3")}最直觀的優勢就是 console.log("2")這裡。
假如console.log("3")是處理流程的主要部分。
console.log("1"),會作一些參數的預處理,console.log("2")很少用。這是常用express的思路,因為主要的邏輯都在console.log("3")里
當然這只是KOA的一方面
在console.log(3)的工作流程中,可能涉及到很多callback。
express可以結合其他的包async promise co等等,對外,只表示為一個方法。
function(req,res){
async([callback1,callback2],callback3)}或function(req,res){new promise(function(a,b{callback1}).then(function(callbakc2)).then(callback3)...KOA可以把每一個callback,當作一個中間件,像之前的
中間件1{callback1next 中間件2next 中間件3 //還沒用,不確定能不能這麼干,直覺應該可以,不然就太水了。}中間件2{callback2}中間件2{callback3}express+第三方工具寫好的一個中間件=koa不用第三方工具的3個中間件
至於以上部分推崇yield generator的,沒有koa又不是不能用。
見仁見智吧。
個人感覺玩玩還行實際雞肋新項目可以考慮舊項目沒必要遷移性能比express稍微差一點,我在項目中使用koa+ES6, 使用了很多的Promise和yield,減少了縮進和callback,代碼更加簡潔,可維護性更高;比起性能的略微減弱,開發效率的提升和維護成本是划算的!使用co還不如直接使用ES7的async/await,這樣就不需要用co來包一個generator了;
這裡代碼執行仍是非同步運行的,只是寫代碼的方式發生變化而已,你任然可以執行一些並行的操作比如Promise.all()感覺koa2很多方面越來越像tornado了....
既然是寫webapi,從我3年的loopback框架使用經驗來看,loopback 秒殺koa,而且koa對於express的中間件的兼容簡直就是噩夢 ,詳情自己點這個國外的對比連接:StrongLoop | Comparing Express, Restify, hapi and LoopBack for building RESTful APIs
我想強調的是koa不是非同步處理的框架,而是基於非同步處理框架co做的一套web框架。
yield不是koa的東西,不要弄混了好嗎!
如果評價co,yield,我舉雙手贊成,太好用了,我現在完全擺脫不了co
如果評價koa這套web框架,不敢恭維。
我個人更偏向於web框架用express,非同步處理用co。
兩個原因1.express+co更靈活2.更豐富的中間件。express社區活躍度遠超過koa。沒記錯的話,express的github star有23000+,koa只有4000+。很多優秀的中間件沒有co的版本。比如node-wechat非同步就是非同步,這些模式只是讓代碼看起來同步,只是協助程序猿的思維,並不是說這就不是非同步了,如果一個程序猿沒有能夠真正接受非同步思維,用了這些也是徒勞。不知道說得對不對
那又該如何理解 koa 應用直接修改 context 的 API 設計呢?總之寫法上沒 express 好。
在 express 的寫法: res.send("xxx") 。
在 koa 上 的寫法:context.body = "xxx"。
很明顯,第二種寫法在主流的 eslint 上也是不推薦的
等koa2出正式版以後我就從express轉過來
async/await 真是太舒服了之前用express,現在開始用koa了,最大的好處是跟非同步說拜拜,偶爾非同步同步穿插特爽,看好它,學koa最好先學express
yield 很方便,理解起來也不難吧,JavaScript 程序員會不理解非同步?
本是同根生 相煎何太急
還是等koa2吧 ,現在感覺這塊變得太快,但伺服器端不能像前端那樣想改就改koa確實比express舒服,但思維需要轉換,特別是團隊開發需要都能跟上才行
tornado,莫名其妙被遺忘了
推薦閱讀:
※Object.create Reflect.setPrototypeOf 哪個比較好?
※js中什麼技術能合併多個前端請求,並生成一個json文件發送?
※Node.js 都應用在什麼項目上?這些項目為什麼選擇 Node.js?
※如何利用mongodb+node.js完成一個搜索的功能?
※有哪些比較好用的nodejs模塊?