热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

nodejs框架对比:koa和express

目前比较流行的nodejs框架有express、koa、egg.js,还有就是和ts相

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

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

什么是洋葱模型?

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

nodejs框架对比:koa和express
借鉴张图:洋葱模型

穿进来时: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/,结果如下:
    nodejs框架对比:koa和express
    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}!`))
})
nodejs框架对比:koa和express
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是顺序不是严格按照洋葱模型的:

nodejs框架对比:koa和express
Express

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

nodejs框架对比:koa和express
koa

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

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


推荐阅读
  • 【前端工具】nodejs+npm+vue 安装(windows)
    预备先看看这几个是干嘛的,相互的关系是啥。nodejs是语言,类比到php。npm是个包管理,类比到composer。vue是个框架&# ... [详细]
  • 前言:原本纠结于Web 模板,选了Handlebars。后来发现页面都是弱逻辑的,不支持复杂逻辑表达式。几乎要放弃之际,想起了Javascript中eval函数。虽然eval函 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • 前言:原本纠结于Web模板,选了Handlebars。后来发现页面都是弱逻辑的,不支持复杂逻辑表达式。几乎要放弃之际,想起了Javascript中ev ... [详细]
  • JavaScript和Python是用于构建各种应用程序的两种有影响力的编程语言。尽管JavaScript多年来一直是占主导地位的编程语言,但Python的迅猛发展有 ... [详细]
  • DAO设计模式(九)_1.设计分层初步 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • IT方面的论坛太多了,有综合,有专业,有行业,在各个论坛里混了几年,体会颇深,以前是论坛哪里人多 ... [详细]
  • Vue基础一、什么是Vue1.1概念Vue(读音vjuː,类似于view)是一套用于构建用户界面的渐进式JavaScript框架,与其它大型框架不 ... [详细]
  • 技术周报·2021-05-07-小编推荐向现代Javascript转型原文标题:Publish,ship,andinstallmodernJavaScriptforfaste ... [详细]
  • OrbitDBPeer 2 Peer Database using CRDTs
    2019独角兽企业重金招聘Python工程师标准Apeer-to-peerdatabaseforthedecentralizedwebOrbitDBisaserverless ... [详细]
  • 这篇“Webpack是怎么工作的”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大 ... [详细]
author-avatar
li永不言败ly_608
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有