node.js中koa和express的差异对比

 更新时间:2023年05月09日 09:31:13   作者:copyer_xyf  
Express和koa都是服务端的开发框架,服务端开发的重点是对HTTP Request和HTTP Response两个对象的封装和处理,下面这篇文章主要给大家介绍了关于node.js中koa和express的差异对比,需要的朋友可以参考下

前言

最近利用业余的时间,跟着 coderwhy 老师学习 node.js,了解以及掌握一些服务端的常见知识:

fileSystem:文件读取模块。events:事件流Buffer:node 中处理二进制的方式http 创建服务器Stream流的读写操作…

确实学习到了很多东西,填充了自己的知识体系的未知领域。

node.js 也许是前端开发者踏入服务端开发的最好选择。同样的 JavaScript,同样的语法,以及同样的你,基本上可以达到无缝衔接的开发。

对于 node.js 而言,社区里面出现了非常多的框架,快速上手,敏捷开发。

koaexpress 就是其中的比较两个突出的框架。

在阅读下文之前,希望你掌握了 express 和 koa 的基本使用,不然下面内容对你的帮助也许不是那么的大。

koa 和 express 的介绍

express 是一个基于 node.js 平台,快速,开放,极简的 web 开发框架。express 官网

koa 是基于 node.js 平台的下一代 web 开发框架。koa 官网

两个框架都是同一个团队开发的,都是 node.js 中比较优秀的框架。

都是 node.js 框架,同一个团队为什么要开发两个呢?

express 也许是 node.js 最早出的框架,里面集成了大量的中间件,造成了框架的笨重性。团队领队人 TJ 发现了 express 的设计是有缺陷的,如果想要修复这个设计缺陷,就会造成 express 的框架重构。

基于上面的种种原因(当然还有不知道的),就打算重新写一个新的框架->koa,来实现 express 的不足之处。

express 现在有团队中的团员维护,基本上也很少更新了。

koa 由团队领队人 TJ 主要维护。

​ --来自 coderwhy 老师的闲谈

上面的闲谈的内容不重要,当个乐子开心一下就好了。

一起看看 express 和 koa 在 github 上的星标:

可以发现 express 的使用率还是比 koa 高,尽管 express 笨重,设计有缺陷,但是对于开发者而言,当不考虑这些因素情况下,express 还是吃香的。

两者都是同一团队写的两个框架,那么核心的思想肯定是相同的,当然肯定会也存在差异,那么接下来就来重点比较一下其中的差异吧。

koa 和 express 的差异对比

下面主要从两个方面来分析其中的差异:设计架构中间件

因为也是第一次接触 koa (express 以前是接触了的),如果存在有误的地方,请指出来,虚心受教,共同进步。

koa 和 express 的设计架构对比

express 是完整和强大的,里面集成了大量的中间件,比如说:路由,静态资源等中间件。对于开发者而言,技术统一,都是使用 express 内部提供的。

koa 是灵活和自由的,基本上没有集成任何中间件(核心代码只有大致1600行左右),中间件都需要自己去安装。对于开发者而言,选择技术的类型是多样的,丰富的。

webstorm 和 vscode 的使用,都是因人而异,没有谁强谁弱。那么对于 express 和 koa 也是同样的道理,各自有各自优势。

接下来我们一起来听听 express 和 koa 独白:

express:hi,koa,我俩同处一体,我俩比比?

koa:???

express:我俩的发动机都是中间件,我有三个兄弟:requestresponsenext,你有几个兄弟呢?

koa:额,我有两个兄弟:contextnext。不过我这 context 兄弟很厉害,以一敌二(request,response)。

express:我自带路由(Router),直接使用即可,你呢?

koa:安装。(koa-router 或者 @dva/router

express:我可以自己暴露静态资源,你呢?

koa:安装。(koa-static

express:我只需要配置一下,就可以解析客户端传递 application/json 的格式数据,你呢?

koa:还是安装。(koa-bodyparser

express:你能不能不要安装呀,你就没有自带的?我还是只需要配置一下,就可以解析客户端传递 x-www-form-urlencoded 的格式数据,你呢?

koa:哈哈哈,不好意思,我不用配置,我也能解析 x-www-form-urlencoded 的格式数据。

koa:我还能安装 @koa/multer 来实现文件上传,你自带了吗?

express:额。。。我这个还真没自带,我也需要安装 multer 来实现。

koa:让你装 xxx。你我本是同根生,相煎何太急,和平相处不行嘛。

express:。。。

TJ:莫吵了,把你俩创建出来,设计理念本就是不相同的。express 你走的完整路线,koa 走的是灵活路线,所以不用相互较劲,和气生财。

koa 和 express 的中间件对比

express 和 koa 的核心,都是中间件。

简单的来说,理解了中间件,也就理解了express 和 koa。

何为中间件?

那么何为中间件呢?

express 和 koa 都能创建一个服务器实例 app,那么给 app 传入一个回调函数,那么该回调函数就被称为中间件(middleware)

express 创建中间件:

// 方式一:use(fn)
app.use((req, res, next) => {})
// 方式二:use(path, fn)
app.use('/', (req, res, next) => {})
// 方式三:method(path, fn)
app.get('/', (req, res, next) => {})
// 方式四:method(path, fn1, fn2, fn3)
app.get('/', (req, res, next) => {}, (req, res, next) => {})

koa 创建中间件:

// 方式一:use(fn)
app.use((ctx, next) => {})
// 方式二:use(path, fn)
app.use('/', (ctx, next) => {})

在这里就不展开怎么使用中间件了,我相信你会的,express 和 koa 的中间件道理是相同的。

中间件的执行顺序(同步,异步)

express 同步

app.use((req, res, next) => {
  console.log("中间件01: next前");
  next();
  console.log("中间件01: next后");
});
app.use((req, res, next) => {
  console.log("中间件02: next前");
  next();
  console.log("中间件02: next后");
});
app.use((req, res, next) => {
  console.log("中间件03")
});

express 异步

function mockAsync () {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(321)
    }, 1000)
  })
}
app.use((req, res, next) => {
  console.log("中间件01: next前");
  next();
  console.log("中间件01: next后");
});
app.use((req, res, next) => {
  console.log("中间件02: next前");
  next();
  console.log("中间件02: next后");
});
app.use(async (req, res, next) => {
  const data = await mockAsync()
  console.log("中间件03: next前");
});

koa 同步

app.use((ctx, next) => {
  console.log('中间件01: next前');
  next()
  console.log('中间件01: next后');
})
app.use((ctx, next) => {
  console.log("中间件02: next前");
  next();
  console.log("中间件02: next后");
});
app.use((ctx, next) => {
  console.log("中间件03");
});

koa 异步

function mockAsync() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(321);
    }, 1000);
  });
}
app.use((ctx, next) => {
  console.log('中间件01: next前');
  next()
  console.log('中间件01: next后');
})
app.use((ctx, next) => {
  console.log("中间件02: next前");
  next();
  console.log("中间件02: next后");
});
app.use(async (ctx, next) => {
  const res = await mockAsync()
  console.log("中间件03");
});

上面四个案例,分别从:

  • express 同步
  • express 异步
  • koa 同步
  • koa 异步

来分析了中间的执行顺序,可以得出两点结论:

  1. 无论是 express 还是 koa,当中间件是同步代码并且调用了 next 函数,那么程序运行就会先执行每个中间件next函数之前的代码,当执行到最后一个中间件时,又会回滚执行每个中间件next 函数后的代码(类似于 数据结构中的 first in last out)。
  2. 无论是 express 还是 koa,当遇到中间件中存在异步代码,就会停止向下执行,而是回到上一个中间件继续执行。

所以对于 express 和 koa 在中间件执行上,**表现形式**上是相同的。

而不相同之处就是在于 express 和 koa 在针对中间件存在异步代码时,**处理方式**不同(简单的来说也就是内部的 next 函数实现不同)。

koa 和 express 不同的异步处理方式

假如存在这样的一个案例:存在两个中间件,一个是业务接口处理的中间件,一个是针对处理相同数据的中间件(比如:针对每个接口返回用户信息),这里的获取用户信息,就是异步操作。

那么针对 express 会写出以下代码:

function getUserInfo () {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({name: 'copyer', sex: 'man'})
    }, 1000)
  })
}
app.get('/list', (req, res, next) => {
  const list = [
    { id: "1", content: "列表1" },
    { id: "2", content: "列表2" },
  ];
  next();
  res.json({
    list,
    userInfo: req?.userInfo // 返回用户信息,需要通过下个中间件来获取
  })
});
app.use(async (req, res, next) => {
  // mock 异步代码,拿到用户信息
  const data = await getUserInfo();
  console.log(data); // { name: 'copyer', sex: 'man' }
  req.userInfo = data; // 设置用户信息
});

当我们访问 list 接口时,发现是拿不到用户信息(userInfo),因为遇到是异步函数,就会停止继续执行下面的代码,而是回到上一个中间件继续执行,所以没有拿到用户信息。

koa 也是同样的道理,但是 koa 却是可以解决这个问题。代码如下:

function getUserInfo() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({ name: "copyer", sex: "man" });
    }, 1000);
  });
}

router.get('/list', async (ctx, next) => {
  const list = [
    { id: "1", content: "列表1" },
    { id: "2", content: "列表2" },
  ];
  await next(); /*****************重点代码*********************/
  ctx.body = {
    list,
    ctx: ctx?.userInfo
  }
});

router.use(async (ctx, next) => {
  const res = await getUserInfo();
  console.log(res); // { name: 'copyer', sex: 'man' }
  ctx.userInfo = res; // 设置用户信息
});

app.use(router.routes())

看上面标记的重点代码,那么就是处理异步的关键。在 next 执行前面,加上一个 await,这样就能正常的拿到用户信息。

await next() 的意思就是等待下个中间件执行完成,那么这样用户信息也就设置成功了。

那么肯定有人这样想,那么我在 express 调用 next 函数时,也加上 await ,是不是也解决了?想法很美好,但是行不通的。为撒?

express 中的 next 函数,返回值一个void,没有返回值。

这里的 next 函数接受一个参数 err,也就是错误信息,针对全局异常处理的收集时,就会使用。

koa 中的 next 函数,返回值一个Promise。

这里的 next 函数不接受参数,所以全局错误的异常处理,需要另想它法。

koa 和 express 在异步处理函数,最大的差别就是 next 函数实现不同,那么也就造成了中间件在异步上的使用不同。

koa 在上一个中间件拿取下一个异步中间件的数据,然后返回。express 却是不行,这是 express 设计上的缺陷。

洋葱模型

想想平时生活中的洋葱,是不是一层一层的。

中间件从上往下(从外往里),然后从下往上(从里往外)执行,无论是同步还是异步都满足,koa 是符合洋葱模型的。

express 是在同步的时候是满足洋葱模型的,但是异步的时候却是不能满足洋葱模型。

总结

这篇主要从设计架构中间件两个方面来解释说明 express 和 koa 之间的差异。

比较差异并不是为了证明谁好谁弱,而是为了另一方面来充分认识框架隐藏的知识点,加深自己理解。

到此这篇关于node.js中koa和express的差异对比的文章就介绍到这了,更多相关koa和express对比内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 浅谈手写node可读流之流动模式

    浅谈手写node可读流之流动模式

    这篇文章主要介绍了浅谈手写node可读流之流动模式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • node.js中的querystring.parse方法使用说明

    node.js中的querystring.parse方法使用说明

    这篇文章主要介绍了node.js中的querystring.parse方法使用说明,本文介绍了querystring.parse的方法说明、语法、接收参数、使用实例和实现源码,需要的朋友可以参考下
    2014-12-12
  • Windows下快速搭建NodeJS本地服务器的步骤

    Windows下快速搭建NodeJS本地服务器的步骤

    本篇文章主要介绍了Windows下快速搭建NodeJS本地服务器的步骤,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-08-08
  • 在Mac OS下使用Node.js的简单教程

    在Mac OS下使用Node.js的简单教程

    这篇文章主要介绍了在Mac OS下使用Node.js的简单教程,Node.js是让JavaScript应用运行于服务器端的框架,需要的朋友可以参考下
    2015-06-06
  • nodejs不用electron实现打开文件资源管理器并选择文件

    nodejs不用electron实现打开文件资源管理器并选择文件

    最近在开发一些小脚本,用 nodejs 实现,其中很多功能需要选择一个/多个文件,或者是选择一个文件夹,这种情况下网上给出的解决方案都是 electron,但是我一个小脚本用 electron 属实有点夸张了,后来转念一想可以通过 powershell 来实现类似的功能,需要的朋友可以参考下
    2024-01-01
  • socket.io实现在线群聊功能

    socket.io实现在线群聊功能

    这篇文章主要为大家详细介绍了socket.io实现在线群聊功能的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04
  • 详解Nodejs之静态资源处理

    详解Nodejs之静态资源处理

    这篇文章主要介绍了详解Nodejs之静态资源处理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • 前端需知nodejs express中间件使用及定义详解

    前端需知nodejs express中间件使用及定义详解

    这篇文章主要为大家介绍了前端需知nodejs express中间件使用及定义详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • node-red教程之dashboard简介与输入型仪表板控件的使用

    node-red教程之dashboard简介与输入型仪表板控件的使用

    Node-red支持自定义节点,当然也就支持自定义图形化的节点。也有优秀的开发者把自己建立的图形化节点无偿分享。这里给出一个股票界面的例子,让大家看一看优秀的node-red界面能做到什么样子
    2022-01-01
  • nodejs与浏览器中全局对象区别点总结

    nodejs与浏览器中全局对象区别点总结

    在本篇文章里小编给大家整理的是一篇关于nodejs与浏览器中全局对象区别点总结内容,对此有需要的朋友们可以学习下。
    2021-12-12

最新评论