资讯专栏INFORMATION COLUMN

再谈express与koa的对比

phodal / 1708人阅读

摘要:以前其实写过一篇和的对比但是后来发现里面有不少谬误所以一直惦记着纠正一下之前的错误尤其关于中间件部分的对比这里的就拿更加简单的代替的执行流程通常我们都说的中间件模型是线性的也就是一个一个往下执行的如下图这么说当然是没错的但是当我们执行下面代

以前其实写过一篇express和koa的对比, 但是后来发现里面有不少谬误. 所以一直惦记着纠正一下之前的错误, 尤其关于中间件部分的对比.

这里的express就拿更加简单的connect代替

connect的执行流程

通常我们都说connect的中间件模型是线性的, 也就是一个一个往下执行的, 如下图:

这么说当然是没错的, 但是当我们执行下面代码的时候可能会有那么一点小小的困惑:

const connect = require("connect")

const app = connect()

app.use(function m1 (req, res, next) {
  console.log("m1")
  next()
  console.log("m1 end")
})

app.use(function m2 (req, res, next) {
  console.log("m2")
  next()
  console.log("m2 end")
})

app.use(function m3 (req, res, next) {
  console.log("m3")
  res.end("hello")
})

app.listen(8080)

当我们访问http://127.0.0.1:8080的时候, 控制台会打印如下:

m1
m2
m3
m2 end
m1 end

这么个结果跟我们上面的模型似乎有点出入, 不是说线性的吗, 为什么next后面的代码还会继续执行? 当然这个我们再之前已经有过结论了, 有兴趣的可以详细瞧瞧, 我们现在直接拿来结果, connect的中间件模型伪代码表示如下:

http.createServer(function (req, res) {
  m1 (req, res) {
    m2 (req, res) {
      m3 (req, res) {}
    }
  }
})

可以看到就是一层一层嵌套的回调, 那么再把我们之前有点疑问的代码简化一下:

http.createServer(function (req, res) {
  console.log("m1")
  m1 (req, res) {
    console.log("m2")
    m2 (req, res) {
      m3 (req, res) {
        console.log("m3")
        res.end("hello")
      }
    }
    console.log("m2 end")
  }
  console.log("m1 end")
})

千万别被上面的回调绕晕了, 就是很简单的回调函数, 一切都解释的通了: 即使res.end之后, 我们的代码还是要继续往下走的, 可以这么说connect的中间件其实也是洋葱形的, 但是因为作为同步代码, 一般不回这么做罢了, 那么上面我们可以重现描述一下connect的中间件模型了:

Koa的执行流程

同样我们再Koa源码分析, 也是说过Koa的中间件模型: 洋葱形

以下面代码为例:

const Koa = require("koa")

const app = new Koa()

app.use(async function m1 (ctx, next) {
  console.log("m1")
  await next()
  console.log("m1 end")
})

app.use(async function m2 (ctx, next) {
  console.log("m2")
  await next()
  console.log("m2 end")
})

app.use(async function m3 (ctx) {
  console.log("m3")
  ctx.body = "hello"
})

app.listen(8080)

访问服务, 输出:

m1
m2
m3
m2 end
m1 end

emm 貌似跟connect没差别, 之前看过一篇文章, 实验到这里得到了一个koa和express的中间件模型没差别的结论, 包括我也是很迷惑, 当然是有差别的, 结论后面讲. 同样这里直接拿出koa中间件的简化模型:

Promise.resolve(async m1 () {
  console.log(m1)
  await Promise.resolve(async m2 () {
    console.log(m2)
    await Promise.resolve(async m3 () {
      console.log(m3)
      ctx.body = "xxx"
     })
     console.log(m2 end)
  })
  console.log(m1 end)
})

我们知道async/await的作用是"同步化"异步操作(看上去如此, 其实不是, 但是我们不需要去管), 那这里的Promise理所当然的被"同步"了, 也就是说console.log(m3 end)的一切异步操作都可以"同步化".

结论

说出结论之前我们其实可以想一下, 既然connect的中间件也是洋葱形的, 那么跟koa一样的用法似乎也没啥毛病, 那么我来设想一下, 我们的服务需要取数据库里的的一个用户假设是getUser吧, getUser当然是异步的. 分别来看看connect和koa的做法吧:

// connect

app.use(function (req, res) {
  getUser(user => res.end(user))
})


// Koa
app.use(async (ctx) => {
  const user = await getUser()
  ctx.body = user
})

当然这么看似乎没啥差别. 那直接给出结论吧(憋): connect的中间件是同步, 不会"等"其他异步操作, koa则可以"等"异步操作. 当然你不等也没啥问题.

有啥问题可以互相交流哈.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/92724.html

相关文章

  • Koa v2.x 中文文档 Koa 对比 Express

    摘要:使用承诺和异步功能来摆脱回调地狱的应用程序,并简化错误处理。它暴露了自己的和对象,而不是的和对象。因此,可被视为的模块的抽象,其中是的应用程序框架。这使得中间件对于整个堆栈而言不仅仅是最终应用程序代码,而且更易于书写,并更不容易出错。 Koa 与 Express 此系列文章的应用示例已发布于 GitHub: koa-docs-Zh-CN. 可以 Fork 帮助改进或 Star 关注更新...

    summerpxy 评论0 收藏0
  • express分析和对比

    摘要:前言目前最新版本是所以本文分析也基于这个版本。源码分析直接切入主题由于目前是一个独立的路由和中间件框架。所以分析的方向也以这两个为主。源码去年的时候有分析过现在对比分析思考下。 前言 目前express最新版本是4.16.2,所以本文分析也基于这个版本。目前从npm仓库上来看express使用量挺高的,express月下载量约为koa的40倍。所以目前研究下express还是有一定意义...

    mmy123456 评论0 收藏0
  • koa-rapid-router超越koa-router性能100多倍

    摘要:我们分别使用这样的原则来测试向每个架构注入个静态路由,测试最末尾的那个。而我们如何做到达到的性能,主要我们在内存中维护了一份静态路由列表,能让程序以最快的速度找到我们需要的。 对比 如果使用nodejs来搭建Service服务,那么我们首选express或者koa,而fastify告诉我们一个数据: Framework Version Router? Requests/sec ...

    Mike617 评论0 收藏0
  • 2017年 JavaScript 框架回顾 -- 后端框架

    摘要:本文是年框架回顾系列的最后的一篇文章,主要介绍的后端框架情况。葡萄城公司成立于年,是全球领先的集开发工具商业智能解决方案管理系统设计工具于一身的软件和服务提供商。 本文是2017年 JavaScript 框架回顾系列的最后的一篇文章,主要介绍 JavaScript 的后端框架情况。 showImg(https://segmentfault.com/img/bV2TPd?w=735&h=...

    xiaoqibTn 评论0 收藏0
  • 精彩文章赏析 - 收藏集 - 掘金

    摘要:掘金原文地址译文出自掘金翻译计划译者请持续关注中文维护链接获取最新内容。由于以下的浏览器市场份额已逐年下降,所以对于浏览器技巧三视觉效果前端掘金揭秘学习笔记系列,记录和分享各种实用技巧,共同进步。 沉浸式学 Git - 前端 - 掘金目录 设置 再谈设置 创建项目 检查状态 做更改 暂存更改 暂存与提交 提交更改 更改而非文件 历史 别名 获得旧版本 给版本打标签 撤销本地更改... ...

    godiscoder 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<