美文网首页前端开发那些事儿
nodejs框架对比:koa和express

nodejs框架对比:koa和express

作者: miao8862 | 来源:发表于2021-05-16 21:43 被阅读0次

    目前比较流行的nodejs框架有expresskoaegg.js,还有就是和ts相关的框架nest.js

    无论是哪种框架,其核心都是基于中间件来实现的,而中间件执行的方式都跟洋葱模型有关,它们的差别主要也是在洋葱模型的执行方式上。

    什么是洋葱模型?

    洋葱模型,就像洋葱一样,一层包裹一层,而nodejs框架的执行就像是中间穿过洋葱的一条线,而每一层洋葱皮就代表一个中间件,进入时穿过多少层,出来时还得穿出多少层,具有先进后出(栈)的特点。

    借鉴张图:洋葱模型

    穿进来时:middleware1 -> middleware2 -> middleware3 -> center
    穿出来时:center -> middleware3 -> middleware2 -> middleware1

    • 穿进来时,中间件的切换主要靠next()关键字来实现的
    • 穿出来时,则是按中间件执行完毕后,按照原路径反回去

    Express

    ExpressNode.js 初期就是一个热度较高、成熟的 Web 框架,并且包括的应用场景非常齐全。同时基于 Express,也诞生了一些场景型的框架,常见的就如上面我们提到的 Nest.js框架

    KOA

    随着nodejs发展,出现了以await/async为核心的语法糖,Express原班人马为了实现一个高可用、高性能、更健壮,并且符合当前Node.js 版本的框架,开发出了可定制KOA框架。
    Egg.js 就是在 KOA 基础上,做了各种比较成熟的中间件和模块,可以说是在 KOA框架基础上的最佳实践,用以满足开发者开箱即用的特性。

    所以在对比差异时,我们主要对比ExpressKOA就可以看出它们间的主要区别

    Express和KOA的差异

    • Express 封装、内置了很多中间件,比如 connectrouter,而 KOA 则比较轻量,开发者可以根据自身需求定制框架;
    • Express 是基于 callback 来处理中间件的,而 KOA 则是基于 await/async
    • 在异步执行中间件时,Express非严格按照洋葱模型执行中间件,而 KOA 则是严格遵循的。
    • Express 使用 callback捕获异常,对于深层次的异常捕获不了,Koa 使用 try catch,能更好地解决异常捕获。

    下面来以例子说明一下两个框架的执行过程不一样的地方:

    Express示例

    1. 写个express服务器
    • app.use:用于中间件和路由的处理。当参数是函数时,匹配所有路由;当参数是字符串时,匹配具体对应的路由
    mkdir node-demo
    cd node-demo
    npm init -y
    mkdir src
    touch express.js
    
    const express = require('express')
    const app = express()
    const port = 3000
    
    const server = app.listen(port, () => {
      const host = server.address().address
      const port = server.address().port
      console.log(`Express server is listening on ${host}:${port}!`)
    })
    
    app.use((req, res, next) => {
      console.log('middleware1 start')
      next(); // 跳到下一层洋葱中间件
      console.log('middleware1 end')
    })
    
    app.use((req, res, next) => {
      console.log('middleware2 start')
      next(); // 跳到下一层洋葱中间件
      console.log('middleware2 end')
    })
    
    app.use((req, res, next) => {
      console.log('middleware3 start')
      next(); // 跳到下一层洋葱中间件
      console.log('middleware3 end')
    })
    
    app.get('/', (req, res) => {
      res.send('hello express')
    })
    
    
    1. 启动服务
      node ./src/express-test.js
    2. 在浏览器访问http://localhost:3000/,结果如下:
      express服务器
    3. 关闭和管理服务
      关闭服务的操作:在当前目录下ctrl+c结束进程

    KOA示例

    KOA的用法其实和Express差不多,只不过Express内置了router,而KOA需要自己定制:

    1. 安装:npm i koa koa-router chalk
    2. 中间件的方法和Express基本一样,只不过将req, res参数换成了上下文ctx
    3. 设置路由需要用路由实例方法 router.get 方式,且要把路由实例设置到koa实例上app.use(router.routes())
    const chalk = require('chalk')
    const Koa = require('koa')
    const Router = require('koa-router')
    const app = new Koa()
    const router = new Router()
    const port = 9000
    
    // 使用ctx上下文
    app.use((ctx, next) => {
      console.log('middleware1 start')
      next(); // 跳到下一层洋葱中间件
      console.log('middleware1 end')
    })
    
    app.use((ctx, next) => {
      console.log('middleware2 start')
      next(); // 跳到下一层洋葱中间件
      console.log('middleware2 end')
    })
    
    app.use((ctx, next) => {
      console.log('middleware3 start')
      next(); // 跳到下一层洋葱中间件
      console.log('middleware3 end')
    })
    router.get('/', (ctx) => {
      ctx.body = 'Hello koa!'
    })
    
    
    // 使用router
    app.use(router.routes())
    app.listen(port, 'localhost', () => {
      console.log(chalk.yellow(`Express server is listening on ${port}!`))
    })
    
    koa服务器

    可以看到如果是中间件中的代码是同步的时候,两者的的执行顺序是一样的。现在修改一下:

    1. 增加一个执行异步操作的中间件
    2. 每一个中间件,都增加上async await处理
    // 这里只举一例子,其它的中间件是一样的
    app.use(async (req, res, next) => {
      console.log('middleware1 start')
      await next(); // 跳到下一层洋葱中间件
      console.log('middleware1 end')
    })
    app.use(async (req, res, next) => {
      console.log('async start');
      await next();
      await new Promise(
          (resolve) => 
              setTimeout(
                  () => {
                      console.log(`wait 1000 ms end`);
                      resolve()
                  }, 
              1000
          )
      );
      console.log('async end');
    });
    

    此时,再观察两者的输出顺序:

    Express是顺序不是严格按照洋葱模型的:

    Express

    KOA的顺序是严格按照洋葱模型的:

    koa

    发生这样的原因是两者基于的nodejs的版本不一样导致的。

    参考:
    https://blog.csdn.net/xgangzai/article/details/109108387
    https://www.jianshu.com/p/6f7930687835/

    相关文章

      网友评论

        本文标题:nodejs框架对比:koa和express

        本文链接:https://www.haomeiwen.com/subject/lpqxjltx.html