zoukankan      html  css  js  c++  java
  • Node.js 框架对比之 Express VS Koa

    背景

    上图是一个典型的采用 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 等功能都移除了,使得框架本身更轻量。 缺点:社区相对较小

  • 相关阅读:
    泛社交泛泛之交也很重要
    iOS 切后台挂机
    iOS 导航栏translucent用法
    iOS 中UIButton中文字换行
    iOS 给UIimageView添加UITapGestureRecognizer手势点击事件
    iOS15UITableView多了白条,导航栏和Tabbar变成白色和标题变黑处理总结属性变化和原来基本的导航栏属性总结记录(看到就更新)
    iOS延时定时功能
    iOS uiview添加背景图案
    iOS 导航栏返回把样式带回前面怎么办
    iOS 识别图片二维码demo,复制粘贴即用
  • 原文地址:https://www.cnblogs.com/sybboy/p/6418526.html
Copyright © 2011-2022 走看看