背景

上图是一个典型的采用 Node.js 开发 web 应用的前后端结构,下面介绍一下 Node 服务层在其中的作用以及使用 Node.js 的一些优劣。

Node 服务层作用:

  1. 请求代理 传统做法是后端提供 api 供前端直接调用,但后端逐渐趋于服务化,直接调用面临的问题有:

    • 跨域

    • 数据需要二次加工

    • 后端服务部署在内网时,前端无法直接调用

  2. 路由

  3. 模板渲染

使用 Node.js 的优势:

  1. 前后端分离,节省沟通、联调成本。

  2. 生态圈繁荣,第三方模块很多,合理使用可以大量提升开发效率。

  3. 处理高并发场景性能更高,适合 web 应用。

使用 Node.js 的劣势:

  1. js 是弱类型语言,可靠性不高,潜在问题很难发现。

  2. 不适合 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的更多相关文章

  1. [转]Node.js框架对比:Express/Koa/Hapi

    本文转自:https://www.cnblogs.com/souvenir/p/6039990.html 本文翻译自: https://www.airpair.com/node.js/posts/no ...

  2. [译]Node.js框架对比:Express/Koa/Hapi

    本文翻译自: https://www.airpair.com/node.js/posts/nodejs-framework-comparison-express-koa-hapi 1.介绍 直至今日, ...

  3. Node.js实现RESTful api,express or koa?

    文章导读: 一.what's RESTful API 二.Express RESTful API 三.KOA RESTful API 四.express还是koa? 五.参考资料 一.what's R ...

  4. node.js框架express的安装

    node.js框架express的安装 首先假定你已经安装了 Node.js,接下来为你的应用创建一个目录,然后进入此目录并将其作为当前工作目录. $ mkdir myapp $ cd myapp 通 ...

  5. 不可错过的Node.js框架

    前言 Node.js是由Ryan Dahl于2009年创建的.它是一个开源的跨平台运行时环境,用于开发服务器端和网络应用程序,它是基于Google Chrome V8 JavaScript引擎构建的. ...

  6. 13 款惊艳的 Node.js 框架——第1部分

    [编者按]本文作者为 Peter Wayner,主要介绍13款至精至简的 Node.js 框架,帮助你简化高速网站.丰富 API 以及实时应用的开发流程.本文系国内 ITOM 管理平台 OneAPM ...

  7. 【转】node.js框架比较

    我偶然间看到这篇文章,转这个文章并没有什么含义,仅仅是感觉总结的不错,对于新学node的友友们来说希望这篇文章为大家对 Node.js 后端框架选型带来一些帮助,学习不再迷茫,也是让我有个保存,以后参 ...

  8. Node.js 框架

    Node.js的是一个JavaScript平台,它允许你建立大型的Web应用程序.  Node.js的框架平台使用JavaScript作为它的脚本语言来构建可伸缩的应用. 当涉及到Web应用程序的开发 ...

  9. LoopBack – 开源的,可扩展的 Node.js 框架

    LoopBack 是建立在 Express 基础上的开源 Node.js 框架,专门为 Mobile,Web 和其他设备做了优化.LoopBack 能够连接到多个数据源,使用 Node.js 编写业务 ...

随机推荐

  1. 树莓派_实现摄像头的拍照、监控与录像(Raspiberry PI Camera 5W)

    学无止境    前言:大家好,欢迎来到誉雪飞舞的博客园,我的每篇文章都是自己用心编写, 算不上精心但是足够用心分享我的自学知识,希望大家能够指正我,互相学习成长. 转载请注明:https://www. ...

  2. Dos命令 WIN10 WIFI命令

    设置WIFI命令: netsh wlan set hostednetwork ssid=T key=123456798 mode=allow netsh wlan start hostednetwor ...

  3. 简单的opengl步骤模板

    以下内容整理自:https://learnopengl-cn.github.io/01%20Getting%20started/03%20Hello%20Window/ 一.初始化 glfw 并设置相 ...

  4. Django 使用第三方服务发送电子邮件

    在 Django 网站中使用 mailgun 的邮件收发服务. 1.在 mailgun 官网上注册个账号(免费,免费账号每个月有10000条收发邮件的服务,对我来说已经完全够用了),注册完成后界面如图 ...

  5. 【arc074e】RGB Sequence dp

    Description ​ 丰泽爷今天也在愉快地玩Minecraft! ​ 现在丰泽爷有一块1∗N1∗N的空地,每个格子按照顺序标记为11到NN.丰泽爷想要在这块空地上铺上红石块.绿宝石块和钻石块作为 ...

  6. 【BZOJ2839】集合计数 容斥原理+组合数

    Description 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得 它们的交集的元素个数为K,求取法的方案数,答案模1000000007 ...

  7. hexo的jacman主题配置

    获得更多资料欢迎进入我的网站或者 csdn或者博客园 这是在我搭建博客时用的主题,这个主题时基于pacman修改的,同时我也是借助于wuchong同时他还在一直更新.一下时我的一些基本配置: 相关文章 ...

  8. 大型php网站性能和并发访问优化方案(转载自php中文网)

               网站性能优化对于大型网站来说非常重要,一个网站的访问打开速度影响着用户体验度,网站访问速度慢会造成高跳出率,小网站很好解决,那对于大型网站由于栏目多,图片和图像都比较庞大,那该怎 ...

  9. JS 方法注入 attachEvent

    写法1: <html> <head> <title></title> <script language="javascript" ...

  10. Qt 学习之路 2(74):线程和 QObject

    Home / Qt 学习之路 2 / Qt 学习之路 2(74):线程和 QObject Qt 学习之路 2(74):线程和 QObject  豆子  2013年12月3日  Qt 学习之路 2  2 ...