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 的一个同步逻辑代码吧:
- callback 和 事件版本: https://github.com/cnpm/cnpmjs.org/blob/3526c9eff7616098ed1cbd52378198f8b2b77de4/proxy/sync_module_worker.js
- co 版本: https://github.com/cnpm/cnpmjs.org/blob/master/proxy/sync_module_worker.js
祝大家早日用上 koa 和 co
:)
原文地址: http://fengmk2.cnpmjs.org/blog/2014/03/koa-vs-connect.html
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);
这段代码使用了 connect
和 eventproxy
来处理异步操作。尽管这种方式能够有效避免回调地狱(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);
在这段代码中,我们使用了 koa
和 Promise
来处理异步操作。这种方式不仅更易于理解和维护,而且代码结构也更加清晰。通过 await
关键字,我们可以按顺序写出异步操作,而不需要嵌套的回调函数。
神马?没多大差别?
如果你觉得这两段代码看起来差不多,那说明你对现代 JavaScript 异步编程已经有了很好的理解。为了进一步展示 koa
的优势,可以看看 cnpm
项目中的同步逻辑代码。以下是两种不同的实现方式:
通过对比可以看出,使用 koa
和 co
的代码更加简洁和易读。
希望这些示例代码能帮助你更好地理解 koa
相对于 connect
的优势,并且逐步过渡到使用 koa
进行开发。
看来你们是完全拥抱koa的节奏哈
这个拥抱koa的节奏啦,空了我也试试!
即将koa!
看上去好吊的感觉,把lua那套都搞进来了。。当时就应该弄node.lua~
哈哈, js原生支持, 现在不用纠结callback了
暂时看不出比较大的区别,有空学习一下KOA,感觉NBHH的。。。。。
楼主借你宝地问个问题… 能告诉我上github的方法不? 用goagent 速度一坨shi啊 … 看你天天很活跃,你们是用什么方式上的啊 先谢谢啦
185.31.16.184 github.global.ssl.fastly.net
这个是说如果不是在 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 的这种设计使开发者更容易理解和维护异步代码,因为它更接近同步代码的编写方式。