Node.js 框架对比之 Express VS Koa
背景
上图是一个典型的采用 Node.js 开发 web 应用的前后端结构,下面介绍一下 Node 服务层在其中的作用以及使用 Node.js 的一些优劣。
Node 服务层作用:
请求代理 传统做法是后端提供 api 供前端直接调用,但后端逐渐趋于服务化,直接调用面临的问题有:
跨域
数据需要二次加工
后端服务部署在内网时,前端无法直接调用
路由
模板渲染
使用 Node.js 的优势:
前后端分离,节省沟通、联调成本。
生态圈繁荣,第三方模块很多,合理使用可以大量提升开发效率。
处理高并发场景性能更高,适合 web 应用。
使用 Node.js 的劣势:
js 是弱类型语言,可靠性不高,潜在问题很难发现。
不适合 CPU 密集型的应用,如视频编解码。
Node.js 框架介绍
提到 Node.js 开发,不得不提目前炙手可热的2大框架 Express 和 Koa。
Express 诞生已有时日, 是一个基于 Node.js 平台的极简、灵活的 web 应用开发框架,主要基于 Connect 中间件,并且自身封装了路由、视图处理等功能,使用人数众多。
Koa 相对更为年轻, 是 Express 原班人马基于 ES6 新特性重新开发的框架,主要基于 co 中间件,框架自身不包含任何中间件,很多功能需要借助第三方中间件解决,但是由于其基于 ES6 generator 特性的异步流程控制,解决了 "callback hell" 和麻烦的错误处理问题,大受开发者欢迎。Koa 目前正式版本是 1.2.4,Koa 团队表示 2.0 版本需要 node 支持 async/await 时才会发布。
示例
Hello World
两者创建一个基础的 Web 服务都非常简单,写法也基本相同,最大的区别是路由处理 Express 是自身集成的,而 Koa 需要引入中间件。
// Express
var express = require('express')
var app = express()
app.get('/', function (req, res) {
res.send('Hello World!')
})
app.listen(3000)
// Koa
var koa = require('koa')
var route = require('koa-route')
var app = koa()
app.use(route.get('/', function *(){
this.body = 'Hello World'
}))
app.listen(3000)
Views
Express 自身集成了视图功能,提供了 consolidate.js 功能,支持几乎所有 JavaScript 模板引擎,并提供了视图设置的便利方法。 Koa 需要引入 co-views 中间件。
// Express
var express = require('express')
var app = express()
app.set('views', __dirname + '/views')
app.set('view engine', 'jade')
app.get('/', function (req, res) {
res.render('index', {
title: 'bilibili'
})
})
// Koa
var koa = require('koa')
var route = require('koa-route')
var views = require('co-views')
var render = views(__dirname + '/views', {
default: "jade"
})
var app = koa()
app.use(route.get('/', function *() {
this.body = yield render('index', {
title: 'bilibili'
})
}))
HTTP Request
两个框架都封装了HTTP Request对象,有一点不同是 Koa v1 使用 this 取代 Express 的 req、res。
// Express
var app = require('express')()
app.get('/room/:id', function (req, res) {
console.log(req.params)
})
// 获取POST数据需要 body-parser 中间件
var bodyParser = require('body-parser')
app.use(bodyParser.json())
app.post('/sendgift', function (req, res) {
console.log(req.body)
})
// Koa
var app = require('koa')()
var route = require('koa-route')
app.use(route.get('/room/:id', function *() {
console.log(this.req.query)
}))
// 获取POST数据需要 co-body 中间件
var parse = require('co-body')
app.use(route.post('/sendgift', function *() {
var post = yield parse(this.request)
console.log(post)
}))
Express 和 Koa 的区别
异步流程控制
Express 采用 callback 来处理异步,Koa v1 采用 generator,Koa v2 采用 async/await。
下面分别对 js 当中 callback、promise、generator、async/await 这四种异步流程控制进行了对比,
generator 和 async/await 使用同步的写法来处理异步,明显好于 callback 和 promise,async/await 在语义化上又要比 generator 更强。
// callback
var api1 = 'https://anapioficeandfire.com/api/characters/583'
var api2 = 'https://anapioficeandfire.com/api/characters/584'
function fetchData () {
$.ajax({
type: 'GET',
url: api1,
dataType: 'json',
success: function (data1) {
$.ajax({
type: 'GET',
url: api2,
dataType: 'json',
success: function (data2) {
console.log(`${data1.name} and ${data2.name} are two characters in Game of Thrones`)
}
})
}
})
}
fetchData()
// Promise
var api1 = 'https://anapioficeandfire.com/api/characters/583'
var api2 = 'https://anapioficeandfire.com/api/characters/584'
function fetchData () {
fetch(api1).then(res1 => {
res1.json().then(data1 => {
fetch(api2).then(res2 => {
res2.json().then(data2 => console.log(`${data1.name} and ${data2.name} are two characters in Game of Thrones`))
})
})
})
}
fetchData()
// generator
var api1 = 'https://anapioficeandfire.com/api/characters/583'
var api2 = 'https://anapioficeandfire.com/api/characters/584'
function *fetchData () {
var name1 = yield request(api1)
var name2 = yield request(api2)
console.log(`${name1} and ${name2} are two characters in Game of Thrones`)
}
function request (url) {
fetch(url).then(res => res.json()).then(data => it.next(data.name))
}
var it = fetchData()
it.next()
// async/await
var api1 = 'https://anapioficeandfire.com/api/characters/583'
var api2 = 'https://anapioficeandfire.com/api/characters/584'
async function fetchData () {
var name1 = await request(api1)
var name2 = await request(api2)
console.log(`${name1} and ${name2} are two characters in Game of Thrones`)
}
function request (url) {
return fetch(url).then(res => res.json()).then(data => data.name)
}
fetchData()
错误处理
Express 使用 callback 捕获异常,对于深层次的异常捕获不了,Koa 使用 try catch,能更好地解决异常捕获。
// Express callback
app.use(function (err, req, res, next) {
console.error(err.stack)
res.status(500).send('Something broke!')
})
// Koa generator
app.use(function *(next) {
try {
yield next
} catch (err) {
this.status = err.status || 500
this.body = { message: err.message }
this.app.emit('error', err, this)
}
})
// Koa async/await
app.use(async (ctx, next) => {
try {
await next()
} catch (err) {
ctx.status = err.status || 500
ctx.body = { message: err.message }
ctx.app.emit('error', err, this)
}
})
总结
Express
优点:线性逻辑,通过中间件形式把业务逻辑细分、简化,一个请求进来经过一系列中间件处理后再响应给用户,清晰明了。 缺点:基于 callback 组合业务逻辑,业务逻辑复杂时嵌套过多,异常捕获困难。
Koa
优点:首先,借助 co 和 generator,很好地解决了异步流程控制和异常捕获问题。其次,Koa 把 Express 中内置的 router、view 等功能都移除了,使得框架本身更轻量。 缺点:社区相对较小
Node.js 框架对比之 Express VS Koa的更多相关文章
- [转]Node.js框架对比:Express/Koa/Hapi
本文转自:https://www.cnblogs.com/souvenir/p/6039990.html 本文翻译自: https://www.airpair.com/node.js/posts/no ...
- [译]Node.js框架对比:Express/Koa/Hapi
本文翻译自: https://www.airpair.com/node.js/posts/nodejs-framework-comparison-express-koa-hapi 1.介绍 直至今日, ...
- Node.js实现RESTful api,express or koa?
文章导读: 一.what's RESTful API 二.Express RESTful API 三.KOA RESTful API 四.express还是koa? 五.参考资料 一.what's R ...
- node.js框架express的安装
node.js框架express的安装 首先假定你已经安装了 Node.js,接下来为你的应用创建一个目录,然后进入此目录并将其作为当前工作目录. $ mkdir myapp $ cd myapp 通 ...
- 不可错过的Node.js框架
前言 Node.js是由Ryan Dahl于2009年创建的.它是一个开源的跨平台运行时环境,用于开发服务器端和网络应用程序,它是基于Google Chrome V8 JavaScript引擎构建的. ...
- 13 款惊艳的 Node.js 框架——第1部分
[编者按]本文作者为 Peter Wayner,主要介绍13款至精至简的 Node.js 框架,帮助你简化高速网站.丰富 API 以及实时应用的开发流程.本文系国内 ITOM 管理平台 OneAPM ...
- 【转】node.js框架比较
我偶然间看到这篇文章,转这个文章并没有什么含义,仅仅是感觉总结的不错,对于新学node的友友们来说希望这篇文章为大家对 Node.js 后端框架选型带来一些帮助,学习不再迷茫,也是让我有个保存,以后参 ...
- Node.js 框架
Node.js的是一个JavaScript平台,它允许你建立大型的Web应用程序. Node.js的框架平台使用JavaScript作为它的脚本语言来构建可伸缩的应用. 当涉及到Web应用程序的开发 ...
- LoopBack – 开源的,可扩展的 Node.js 框架
LoopBack 是建立在 Express 基础上的开源 Node.js 框架,专门为 Mobile,Web 和其他设备做了优化.LoopBack 能够连接到多个数据源,使用 Node.js 编写业务 ...
随机推荐
- this指针------新标准c++程序设计
背景: c++是在c语言的基础上发展而来的,第一个c++的编译器实际上是将c++程序翻译成c语言程序,然后再用c语言编译器进行编译.c语言没有类的概念,只有结构,函数都是全局函数,没有成员函数.翻 ...
- git中文乱码问题
控制台中输入:git config --global core.quotepath false
- CLion中出现错误add_dependencies called with incorrect number of arguments解决
出现这个错误以后我以为是IDE出现问题了,可是重新启动,打开其他的工程文件以后发现并没有这个错误,但是新建的文件却报错 然后就打开其他工程的Cmake_list.txt文件,发现最后一行是有工程文件夹 ...
- scrapy 爬取天猫商品信息
spider # -*- coding: utf-8 -*- from urllib.parse import urlencode import requests import scrapy impo ...
- [jvm]java内存模型
一.java内存模型 Java虚拟机规范中试图定义一种Java内存模型(Java Memory Model,JMM)来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一 ...
- 并查集简述 (HDU-1213-How Many Tables)
并查集主要解决集合的有关运算,主要操作是查找操作和并操作. 1.集合的储存方式. 为便于查找,集合通常以树结构储存,每个元素分 数据域和指针域,可以用链式储存,也可以用结构数组储存,用根节点来表示一个 ...
- rpm命令-以jenkins为例
1.列出所有安装的Jenkins rpm -qa | grep jenkins 2.软件是否安装:例如:jenkins是否安装 rpm -qa | grep jenkins 3.rpm -ql 列出软 ...
- prcharm 注册码
JetBrains全系列在线激活中心 使用方法: 1. 点击Help,选择Register.打开注册页面. 2. 选择License server, 在License server address 中 ...
- C++_异常3-异常机制throw try catch
下面介绍如何使用异常机制来处理错误. C++异常是对程序运行过程中发生的异常情况的一种响应. 异常提供了将控制权从程序的一部分传递到另一部分的途径. 对异常的处理有3个组成部分: 1)引发异常 -- ...
- windows cmd 切换磁盘
抛砖引玉 切换到D盘根目录——cd /d D: 切换到D:\dev目录——cd /d D:\dev