基于Node.js、Express和Jscex开发的ToDo网站示例

标签: 前端表现 项目扩展 | 发表时间:2011-07-15 16:57 | 作者:jeffz@live.com (老赵) 文涛
出处:http://blog.zhaojie.me/

Jscex的主要使用场景是“JavaScript异步编程”,不过并没有限制是跑在浏览器还是服务器端。最近Node.js很火热,也刚发布了原生的Windows版,不少同学会用它来做一些网站这样的小程序。目前用Node.js开发网站最著名的框架是Express,使用起来也是比较容易的。前段时间看到CNodeJS社区的一篇文章,有同学将一个Python写的ToDo列表网站移植到了Node.js上,我为了推广Jscex,就fork了这个项目,将其修改为基于Jscex的版本,大伙儿可以来比较一下。当然这个网站过于简单,我也正在寻找更合适的项目。

JavaScript是一个没有阻塞特性的语言,因此各类API都会设计为异步,这对于服务器的伸缩性和客户端网页的响应能力都有好处,不过在程序编写上就会遇到各种问题了。例如在ToDo示例中的一个简单的处理函数,因为需要查询数据库,就要写成带回调的样子:

exports.index = function (req, res, next) {
    db.query('select * from todo order by finished asc, id asc limit 50', function (err, rows) {
        if (err) return next(err);
        res.render('index', { todos: rows });
    });
};

db变量用来操作MySQL数据库,它的query方法传入sql(可能还会有参数)并提供一个回调函数,用来提示错误或是返回查询结果。在回调中我们必须判断err是否存在,如果存在便调用next报告框架“出错了”。每个异步操作都必须如此,试想如果在这个查询后还有另一个查询,则还需要进行一次嵌套和err判断。每个处理函数都是如此,这也是异步编程的烦恼之一:难以进行统一的异常处理,处理代码总是需要分散在各处,一不小心就变成“野异常”,还很难排查出来。

我将ToDo网站简单地Jscex化了一下。首先让MySQL的查询能够接入Jscex(lib\jscex.mysql.js):

exports.jscexify = function (db) {
    db.queryAsync = function () {
        var _this = this;

        var args = [];
        for (var i = 0; i < arguments.length; i++) {
            args.push(arguments[i]);
        }

        var delegate = {
            onStart: function (callback) {

                args.push(function (err, result) {
                    if (err) {
                        callback("failure", err);
                    } else {
                        callback("success", result);
                    }
                });

                _this.query.apply(_this, args);
            }
        };

        return new Jscex.Async.Task(delegate);
    }
}

一般来说,将一个异步接口给Jscex化并不需要那么多代码(最关键的其实只是onStart函数)。这里近30行代码,其中大部分是为了支持“变长”参数,因此queryAsync函数会保留调用时的所有参数,补上一个callback,再去调用query函数本身。此时,便可以去改写之前的index等处理函数了(controllers\todo.js),例如:

exports.index = toHandler(eval(Jscex.compile("async", function (req, res) {

    var todos = $await(db.queryAsync('select * from todo order by finished asc, id asc limit 50'));
    res.render("index", { todos: todos });

})));

toHandler函数的作用,是将一个“接受req和res,返回Task”的函数,封装成标准的“接受req、res和next三个参数”的处理函数,并提供统一的错误处理:

var toHandler = function (asyncFunc) {
    return function (req, res, next) {
        var task = asyncFunc(req, res);
        task.addListener(function () {
            if (task.status == "failed") {
                next(task.error);
            }
        });
        task.start();
    }
}

我在todo.js里保留了原有各个处理函数的实现,感兴趣的朋友可以对比一下它们之前的差别。可惜的是,由于ToDo实在过于简单,Jscex的优势并没有表现出来太多。例如,每个处理程序中只有一个MySQL查询,没有判断和循环,更别说为了充分利用IO并发能力,从而组合多个异步函数了。因此,我最近也一直在寻找更复杂一些的示例,不过似乎用Express的开源网站并不多见,我几乎都想自己写一个了。目前感觉Nodepad似乎还算不错,接下来可能会对它下手。

ToDo网站依赖Express,ejs和MySQL驱动,同时我把Jscex作为添加为它的子模块。如果您要克隆一份ToDo的代码把玩一番,可以:

> git clone git://github.com/JeffreyZhao/todo.git
> cd todo
> git submodule init
> git submodule update
> npm install express ejs mysql
> node server.js

从现在开始,我会在InfoQ中文站上发表一系列关于Jscex的文章,既有关于浏览器端的JavaScript开发,也有在服务器端利用Node.js开发的内容。可能您目前还可能会有所疑惑,例如为什么要使用危险的eval函数,eval和Jscex.compile函数不能封装起来吗?其实在看了我的文章并对Jscex有了基本了解之后,就会发现这些都是以“传统眼光”来看待Jscex时所形成的误解。Jscex的做法的确“另辟蹊径”,否则在JavaScript异步类库已经多如牛毛的情况下,我不知如何让它脱颖而出。

相关 [node js express] 推荐:

無痛安裝 NodeJS 和 Node Framework Express

- Hming - 小惡魔 - 電腦技術 - 工作筆記 - AppleBOY
直接到官網下載 Stable 的版本吧,目前是 node-v0.4.10.tar.gz,也可以先看看 API Document. 安裝 Ububtu 相關套件. 下面會使用最原始的編譯方式,所以必須安裝 g++ 套件,否則下 ./configure 的時候,會吐出來沒有安裝過的套件. 兩種方法:1.用 apt-get install nodejs 2.

node js 断点调试

- - Web前端 - ITeye博客
大部分基于 Node.js 的应用都是运行在浏览器中的,. 例如强大的调试工具 node-inspector. node-inspector 是一个完全基于 Node.js 的开源在线调试工具,提供了强大的调试功能和友好. 的用户界面,它的使用方法十分简便. 首先,使用 npm install -g node-inspector 命令安装 node-inspector,然后在终.

使用js服务端语言nodejs和express建个人站点

- - CSDN博客Web前端推荐文章
使用js服务端语言nodejs和express建个人站点. 作者:田想兵 个人网址: http://www.lovewebgames.com. 今天主题很沉重,因为听说京城又在开会,房价上涨,物价也在涨,还有西湖边上的小松鼠被游客踩死了. 所以说点不开心的事让大伙开心一下,记得一个月前,公司破产,为了生计,我不得不再次投入到找工作的大军中,在杭州,可能做IT行业的技工,都想进阿里淘宝这家杭州标志性的企业,我也不例外,于是投了一份资深前端职位的简历.

什么是Node?

- We_Get - 博客园新闻频道
译者按:前不久Oreilly出了一本小册子“What is Node?”,扼要的讲解了Node的身世和所适用的场景,作者文笔轻松流畅、内容充实,是非常难得的学习资料.   译文全文:http://jayli.github.com/whatisnode/index.html.   作者:Brett McLaughlin ,原文:What is Node?.

Node入门

- - CSDN博客编程语言推荐文章
作者:  Manuel Kiessling. 翻译:  goddyzhao &  GrayZhang &  MondayChen. 本书致力于教会你如何用Node.js来开发应用,过程中会传授你所有所需的“高级”JavaScript知识. 本书绝不是一本“Hello World”的教程. 你正在阅读的已经是本书的最终版.

浅析Hadoop Secondary NameNode,CheckPoint Node,Backup Node

- - CSDN博客云计算推荐文章
Hadoop SecondaryNameNode并不是Hadoop 第二个NameNode,它不提供NameNode服务,而仅仅是NameNode的一个工具. 这个工具帮助NameNode管理Metadata数据. NameNode的HDFS文件信息(即Metadata)记录在内存中,client的文件写操作直接修改内存中的Metadata,同时也会记录到硬盘的Edits文件,这是一个Log文件.

[译]什么是Node?

- blacktulip - Taobao UED Team
译者按:前不久Oreilly出了一本小册子“What is Node?”,扼要的讲解了Node的身世和所适用的场景,作者文笔轻松流畅、内容充实,是非常难得的学习资料. 译文全文:http://jayli.github.com/whatisnode/index.html. 作者:Brett McLaughlin ,原文:What is Node?.

用node作桌面开发

- InterMa - CNode社区
node的定位是,server-side javascript. 但程序员最爱做的事,就是把一个东西用在不该用的地方. 那么,可以把node用在桌面开发上吗. 把Javascript用在桌面开发上,早有先例,比如GTK+的gjs,还有Qt的QML(顺带一提,QML代表着桌面开发的另一个方向,a promising way),GNOME3中,也用javascript作为桌面插件的开发语言.

SATA Express新接口、数据线图解

- Jerry - cnBeta.COM
SATA-IO组织日前宣布,正在着手制定新的高速SATA标准规范,传输带宽将提升到8Gbps和16Gbps,而为达此目标将在SATA中融入PCI-E技术. 很自然地,SATA接口、数据线也将会因此发生变化. SATA-IO目前已经组建了新的数据线和接口工作组,专门用来为SATA Express制定新的接口、数据线规格,预计2011年底完成.