Node.js学习历程


一直做后台开发的我,一直觉得WEB前端开发很神秘,便打算花上一个月业余时间学习了Node.js和Javascript。至于为什么选择Node.js,主要是考虑到Node.js是服务器端的Javascript脚本语言,这对于我一个对浏览器客户端开发毫无经验的人来说,学习更容易些,不需要再学一门服务器端脚本语言,可以节省学习时间。同时在Node启动的很短时间内,社区就已经贡献了大量的扩展库(模块)。其中很多是连接数据库或是其他软件的驱动,这也可以节省开发成本。

这篇文章我想和大家分享一下我从零开始学习Node.js的历程。

一. 初探Node.js

·         朋友推荐了一遍文章:http://howtonode.org/express-mongodb,它很详细地介绍了如何搭建一个使用Node.js的blog网站,我便按照文章上面的步骤先安装node.js,然后使用npm安装依赖的module.

    Install: "c:\Program Files\nodejs\"

    Script: D:\Study_2012\node\blog

    Command: node app.js

然后就可以通过下面的URL来访问我们搭建的blog:


·         下面是介绍node.js的两个不错的网站,大家可以先简单浏览一下:

http://www.nodebeginner.org:入门教材,有中文版

http://www.nodecloud.org/:介绍了node.js的非常受欢迎的一些资源,比如流行的模块·应用引擎

 

·         推荐一个不错的firefox插件Firebug: Debug the javascript/html/css

 

·         下面是Node.js一些较受欢迎的Module

Jade: Jade is the daddy of HTML template engines for Scala

express: A Node web framework

ejs:embeded javascript

eventproxy: An implementation of task/event based asynchronous pattern

mongodb: a NoSQL database

mongoose: a MongoDB object modeling tool designed to work in an asynchronous environment.

nodemailer: Send email using Node.js

 

·         使用mongodb,需要先安装mongodb client,并启动mongodb client:

set PATH=C:\Program Files\nodejs;D:\Study_2012\mongodb-win32-i386-2.0.3-rc0\bin;%PATH%

start mongod.exe --port 27017 --dbpath D:\Study_2012\mongodb-win32-i386-2.0.3-rc0\data\

start mongo.exe localhost:27017

 

下面是一些mongodb常用的命令:

show dbs

use node-mongo-blog

show collections

db.<collection_name>.find()

db.users.remove({email:"user@gmail.com"})

db.users.find({email:"user@gmail.com"})

db.users.find({email:"user@gmail.com"}, {email:1, loginname:2}) //return email and loginname

db.users.update({email:"user@gmail.com"}, {email:"flybirdy@163.com"}) // other fields will be empty

 

·         我还参考了另一个例子todo: http://cnodejs.org/blog/?p=1310, 它使用mysql作为数据库,类似于mongodb, 需要先安装mysql客户端,并创建一个数据库

    cd D:\Study_2012\node\todo

    node server.js

 

ejs和jade是express提供的两种不同的view engine.这里使用了ejs(embeded javascript).

 

下面是mysql常用命令:

mysql> connect <dbname>

mysql> source D:\Study_2012\node\todo\todo.sql

mysql> select * from todo;

 

·         下面是另一个例子:http://cnodejs.org/blog/?p=1703. 它使用node.js, express, JSON, jade搭建了一个静态网站。

cd D:\Study_2012\node\website

node app.js

 

·         上面都是一些相对小的例子,为了更好的理解node.js, 我参考了一个开源项目Node Club. Node Club 是用Node.js和MongoDb开发的新型社区软件,界面优雅,功能丰富,小巧迅速,已在Node.js 中文技术社区 [CNode](http://cnodejs.org) 得到应用,但你完全可以用它搭建自己的社区:

    cd D:\Study_2012\node\node-club

    node app.js

    (启动mongodb client)

    url:  http://localhost:88/

二. 动手做个匿名意见系统
·         后来有朋友说让我帮他做个匿名意见系统,功能简单来说就是用户可以匿名发表自己对公司/部门/同事等的意见,而经理并不知道发表意见的人是谁,并且匿名用户可以查看并回复经理的反馈。我觉得这个功能有点类似Node Club, 在Node Club上发表帖子就类似发表建议,回复帖子就类似于回复建议。而最大的不同的地方在于:
1. Node Club上所有帖子都是所有人可见的,包括匿名用户;而匿名建议系统需要匿名用户只能查看自己发表的建议,不能看到别人的建议。
2. Node Club上匿名用户不可以发表或回复帖子;而匿名建议系统需要提供匿名用户发表建议的功能,并且匿名用户可以回复自己所发表的帖子。
 

这个匿名系统已经上传到https://github.com/clairewu/annoy_advice

 

为了实现匿名系统特有的功能,我主要做了以下修改:

1. 匿名用户发表建议时,需要输入一个与建议相对应的密码。

a) Topic Schema需要增加一个字段pass

需要修改modules/topic.js, 在Topic Schema里面加入字段passwd:

        passwd: {type: String},

b) 修改views/topic/edit.html,增加“密码”和“确认密码”两个输入框

                                <div class='sep10'></div>
                                <div class='control-group'>
                                        <label class='control-label' for='pass'>密码</label>
                                        <div class='controls'>
                                                <input class='input-xlarge' id='pass' name='pass' size='30' type='password' />
                                        </div>
                                </div>
                                <div class='control-group'>
                                        <label class='control-label' for='re_pass'>确认密码</label>
                                        <div class='controls'>
                                                <input class='input-xlarge' id='re_pass' name='re_pass' size='30' type='password' />
                                        </div>
                                </div>


c) 修改controller/topic.js里面的create方法,验证输入的密码和确认密码一致,并且将密码保存到Topic schema中。

                        topic.passwd = pass;

                        topic.save(function(err){

 

2. 匿名用户查看建议时,需同时提供建议编号和对应的密码。

a) 修改app.js, 增加对topic/view的路由

app.get('/topic/view', routes.view_topic);

app.post('/topic/view', routes.view_topic);

 

routes定义了get/post请求对应的处理函数名,比如下面代码定义了/topic/view所对应的处理函数是controller/topic.js里面的view()函数。

        var topic_ctrl = require('../controllers/topic');

        exports.view_topic = topic_ctrl.view;

b) 修改controller/topic.js,增加view()函数,它会使用下面代码,来要求匿名用户输入建议编号和对应的密码

        res.render('topic/view');

 

因为我们在app.js里面定义的view engine是html,并注册了后缀为html的文件将使用ejs模板引擎:

        app.set('view engine', 'html');

        app.register('.html',require('ejs'));

 所以将使用ejs来render topic/view.html.ejs是embeded javascript的缩写,它是Express提供的一种模板引擎,语法与javascript类似。我们可以使用在view.html里面使用<%= variable %>来指定res.render('/topic/view', {variable:value})提供的输入值value.

 
三. 了解Node.js的非阻塞异步特性

·         在实现匿名系统时,我碰到一个奇怪现象,通过这我才真正理解了Node.js的非阻塞异步特性。

 

在说我碰到的奇怪现象前,先解释下Node.js的非阻塞异步特性。下面这句话摘自nodejs.org主页上:

Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.

 

我之前一直以为只要将回调函数作为参数,那么回调函数和被调用函数直接就可以实现异步,如:

function   sleep(n)
{
        var   start=new   Date().getTime();
        while(true)   if(new   Date().getTime()-start> n)   break;
}
 
var func = function(cb){
        cb();
};
var a = 1;
func(function(){
        a = 2;
        sleep(1000);
        console.log("1 " + a);
});
console.log("2 " + a);

将显示:

2 1

1 2

 

实际上,结果是:

1 2

2 1

 

Felix Geisend?rfer的大作Understanding node.js(http://debuggable.com/posts/understanding-node-js:4bd98440-45e4-4a9a-8ef7-0f7ecbdd56cb)里面提到
        in node everything runs in parallel, except your code
实际上是指Node.js里面的I/O model。下面这篇文章介绍了I/O的异步特性及实现:
        http://club.cnodejs.org/topic/4f16442ccae1f4aa2700113b
Node.js是通过多线程来进行I/O操作的。

现在回到我前面提到的奇怪现象,下面是相关代码,我想找到loginname为'gregsong'的User记录,结果发现1处可以取出正确的信息,但是2处仍然还是空.后来才发现原来User.findOne找出匹配的User后,并未立即执行回调函数,而是继续执行2处的操作。也就是说回调函数和2处的操作是并行执行的,并不是先执行回调函数,然后执行2处的操作。

User.findOne({loginname:'gregsong'},function(err,user){
    console.log("01" + id);
        if(err) return next(err);
        if(user){
                //1
                req.session.user = user;
                console.log(req.session.user);
        }else{
                return next();      
        }
});
//2
console.log(req.session.user);

·         express needs layout.html or layout.jade under view directory

·         Debug node.js
首先需要在javascript里面在需要debug的地方加入代码"debugger;":
% node debug myscript.js
< debugger listening on port 5858
connecting... ok
break in /home/indutny/Code/git/indutny/myscript.js:1
  1 x = 5;
  2 setTimeout(function () {
  3   debugger;
debug>

转载本站文章请注明作者和出处:http://blog.csdn.net/crazy_samba ,请勿用于任何商业用途

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值