如何評價 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:

```js

const xTime = async (ctx,next)=&>{

let start = new Date

await 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

不嫌棄的話,可以看我的一個實驗項目

yanke_guo / MessyChat-Server


自從玩了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 中間件2

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

callback1

next 中間件2

next 中間件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模塊?

TAG:Nodejs | Express框架 | koa | co |