Nodejs Hello koa, good bye connect

Nodejs Hello koa, good bye connect

从前的 connect

var connect = require('connect');
var eventproxy = require('eventproxy');
var tair = require('./common/tair');

var app = connect();

// TODO: add render

app.use(function (req, res, next) {
  var ep = eventproxy.create();
  ep.fail(next);

  // 并发取 k1, k2
  tair.get('k1', ep.done('v1'));
  tair.get('k2', ep.done('v2'));

  tair.on('v1', function (v1) {
    // k1 取完接着取 k3
    if (v1) {
      return tair.get('k3', ep.done('v3'));
    }
    ep.emit('v3');
  });

  ep.all('v1', 'v2', 'v3', function (v1, v2, v3) {
    res.render('home.html', {
      v1: v1,
      v2: v2,
      v3: v3
    });
  });
});

app.listen(1984);

这是我在没有遇到 co 和 koa 之前, 一直写的业务逻辑代码. 基于事件机制,

虽然能很好地解决 callback hells, 但是让另外一个人看懂业务逻辑, 不是一件简单的事情.

现在的 koa

var koa = require('koa');
var thunkfiy = require('thunkify-wrap');
var tair = require('./common/tair');

tair.get = thunkfiy(tair.get);

var app = koa();

// TODO: add render

app.use(function *(next) { var ep = eventproxy.create(); ep.fail(next);

// 并发取 k1, k2 var rs = yield [tair.get(‘k1’), tair.get(‘k2’)]; var v1 = rs[0]; var v2 = rs[1]; var v3 = null; if (v1) { // k1 取完接着取 k3 v3 = yield tair.get(‘k3’); }

yield this.render(‘home.html’, { v1: v1, v2: v2, v3: v3 }); });

app.listen(1984);

一切都是回归同步顺序的方式, 从上到下这样顺序写, 顺序执行. 很适合后端编码的思维.

如果大家已经熟悉了事件编程, 或者看惯了 callback, 那么 koa 一开始看起来还是比较奇怪的. 为什么能这么神奇.

一旦大家用上了 koa , 就无法回头写 callback 了.

神马? 没多大差别啊

厄, 看来你的功力不错, 好吧, 那大家来看看 cnpm 的一个同步逻辑代码吧:

祝大家早日用上 koa 和 co

:)

原文地址: http://fengmk2.cnpmjs.org/blog/2014/03/koa-vs-connect.html


16 回复

Nodejs Hello Koa, Goodbye Connect

从前的 Connect

在 Node.js 刚开始流行的时候,connect 是一个非常流行的框架。下面是一个使用 connect 编写的简单应用示例:

var connect = require('connect');
var eventproxy = require('eventproxy');
var tair = require('./common/tair');

var app = connect();

app.use(function (req, res, next) {
  var ep = eventproxy.create();
  ep.fail(next);

  // 并发获取 k1, k2
  tair.get('k1', ep.done('v1'));
  tair.get('k2', ep.done('v3'));

  tair.on('v1', function (v1) {
    // 如果 k1 成功获取,则继续获取 k3
    if (v1) {
      return tair.get('k3', ep.done('v3'));
    }
    ep.emit('v3');
  });

  ep.all('v1', 'v2', 'v3', function (v1, v2, v3) {
    res.render('home.html', {
      v1: v1,
      v2: v2,
      v3: v3
    });
  });
});

app.listen(1984);

这段代码使用了 connecteventproxy 来处理异步操作。尽管这种方式能够有效避免回调地狱(callback hell),但阅读和理解起来仍然比较困难。

现在的 Koa

随着 koa 的出现,编写异步代码变得更加直观和简洁。下面是使用 koa 重写的上述代码:

var koa = require('koa');
var thunkify = require('thunkify-wrap');
var tair = require('./common/tair');

tair.get = thunkify(tair.get);

var app = koa();

app.use(async function (ctx, next) {
  var ep = eventproxy.create();
  ep.fail(next);

  // 并发获取 k1, k2
  var [v1, v2] = await Promise.all([tair.get('k1'), tair.get('k2')]);

  let v3 = null;
  if (v1) {
    // 如果 k1 成功获取,则继续获取 k3
    v3 = await tair.get('k3');
  }

  ctx.body = {
    v1: v1,
    v2: v2,
    v3: v3
  };
});

app.listen(1984);

在这段代码中,我们使用了 koaPromise 来处理异步操作。这种方式不仅更易于理解和维护,而且代码结构也更加清晰。通过 await 关键字,我们可以按顺序写出异步操作,而不需要嵌套的回调函数。

神马?没多大差别?

如果你觉得这两段代码看起来差不多,那说明你对现代 JavaScript 异步编程已经有了很好的理解。为了进一步展示 koa 的优势,可以看看 cnpm 项目中的同步逻辑代码。以下是两种不同的实现方式:

通过对比可以看出,使用 koaco 的代码更加简洁和易读。

希望这些示例代码能帮助你更好地理解 koa 相对于 connect 的优势,并且逐步过渡到使用 koa 进行开发。


早用上了,哈哈~

看来你们是完全拥抱koa的节奏哈

这个拥抱koa的节奏啦,空了我也试试!

即将koa!

看上去好吊的感觉,把lua那套都搞进来了。。当时就应该弄node.lua~

哈哈, js原生支持, 现在不用纠结callback了

暂时看不出比较大的区别,有空学习一下KOA,感觉NBHH的。。。。。

楼主借你宝地问个问题… 能告诉我上github的方法不? 用goagent 速度一坨shi啊 … 看你天天很活跃,你们是用什么方式上的啊 先谢谢啦

楼主有关于koa的性能测试报告吗?现在co文档里提到了性能问题 Currently you must use the --harmony-generators flag when running node 0.11.x to get access to generators. Or use gnode to spawn your node instance. However note that performance degrades quickly compared to 0.11.x.

这个是说如果不是在 0.11.x 的环境下,用 gnode 的话性能会下降很多,如果在 0.11.x,就不会有性能问题

目测楼主是TJ粉,哈哈

好像还是有差吧 代码1 是k1、k2并行取,k3在k1完成后取,不需等k2 代码2 是k1、k2并行取,k3在k1,、k2都完成后才取 是这样吗?

这段帖子主要对比了使用 Connect 和 Koa 来实现异步逻辑的不同方式。Connect 使用传统的回调方式,而 Koa 则通过生成器(Generator)实现了更简洁、易读的异步代码。

示例代码

Connect 示例

var connect = require('connect');
var eventproxy = require('eventproxy');
var tair = require('./common/tair');

var app = connect();

app.use(function (req, res, next) {
  var ep = eventproxy.create();
  ep.fail(next);

  tair.get('k1', ep.done('v1'));
  tair.get('k2', ep.done('v2'));

  tair.on('v1', function (v1) {
    if (v1) {
      tair.get('k3', ep.done('v3'));
    } else {
      ep.emit('v3');
    }
  });

  ep.all('v1', 'v2', 'v3', function (v1, v2, v3) {
    res.render('home.html', {
      v1: v1,
      v2: v2,
      v3: v3
    });
  });
});

app.listen(1984);

Koa 示例

var koa = require('koa');
var thunkify = require('thunkify-wrap');
var tair = require('./common/tair');

tair.get = thunkify(tair.get);

var app = koa();

app.use(function *(next) {
  var ep = eventproxy.create();
  ep.fail(next);

  var [v1, v2] = yield [tair.get('k1'), tair.get('k2')];
  var v3 = null;

  if (v1) {
    v3 = yield tair.get('k3');
  }

  yield this.render('home.html', {
    v1: v1,
    v2: v2,
    v3: v3
  });
});

app.listen(1984);

解释

  • Connect 使用 eventproxy 来处理并发请求,并通过嵌套的回调来管理异步逻辑。
  • Koa 使用生成器函数和 thunkify-wrap 库将 tair.get 方法转换为支持异步操作的函数,从而可以使用 yield 关键字等待异步操作完成。这使得代码更加直观和易于理解。

Koa 的这种设计使开发者更容易理解和维护异步代码,因为它更接近同步代码的编写方式。

回到顶部