内容发布更新时间 : 2024/12/22 17:30:36星期一 下面是文章的全部内容请认真阅读。
Node.js实现一个简单的Web MVC框架---我要看明白的第一个mvc
Node.js是什么
Node让你可以用javascript编写服务器端程序,让javascript脱离web浏览器的限制,像C#、JAVA、Python等语言一样在服务器端运行,这也让一些熟悉Javascript的前端开发人员进军到服务器端开发提供了一个便利的途径。 Node是基于Google的V8引擎封装的,并提供了一些编写服务器程序的常用接口,例如文件流的处理。Node的目的是提供一种简单的途径来编写高性能的网络程序。
(注:1、本文基于Node.js V0.3.6; 2、本文假设你了解JavaScript; 3、本文假设你了解MVC框架;4、本文示例源代码:learnNode.zip) Node.js的性能 hello world 测试:
300并发请求,返回不同大小的内容:
为什么node有如此高的性能?看node的特性。 Node.js的特性 1. 单线程 2. 非阻塞IO 3. Google V8 4. 事件驱动
更详细的了解node请看淘宝UED博客上的关于node.js的一个幻灯片:http://www-slideshare-net/lijing00333/node-js 你好,世界
这,当然是俗套的Hello World啦(hello_world.js):
var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\\n'); }).listen(8124, \http://127.0.0.1:8124/');
require类似于C#的using、Python的import,用于导入模块(module)。node使用的是CommonJS的模块系统。http.createServer 的参数为一个函数,每当有新的请求进来的时候,就会触发这个函数。最后就是绑定要监听的端口。 怎么运行?
当然,是先安装node.js啦。到http://nodejs-org/下载并编译,支持Linux、Mac,也支持windows下的Cygwin。具体的安装说明见:http://howtonode-org/how-to-install-nodejs 装好node后,就可以运行我们的hello world了:
$ node hello_world.js Server running at http://127.0.0.1:8124/
编程习惯的改变?
我们来写一个读取文件内容的脚本:
//output_me.js var fs = require('fs'), fileContent = 'nothing'; fs.readFile(__filename, \{ if(err) { console.log(err); return; } fileContent = file; console.log('end readfile \\n'); }); console.log('doSomethingWithFile: '+ fileContent +'\\n');
这个脚本读取当前文件的内容并输出。__filename是node的一个全局变量,值为当前文件的绝对路径。我们执行这个脚本看一下:
有没发现结果不对呢?打印的fileContent并不是读取到的文件内容,而是初始化的时候赋值的nothing,并且‘end readfile’最后才打印出来。前面我们提到node的一个特性就是非阻塞IO,而readFile就是异步非阻塞读取文件内容的,所以后面的代码并不会等到文件内容读取完了再执行。请谨记node的异步非阻塞IO特性。所以我们需要将上面的代码修改为如下就能正常工作了:
//output_me.js var fs = require('fs'), fileContent = 'nothing'; fs.readFile(__filename, \{ if(err) { console.log(err); return; } fileContent = file; //对于file的处理放到回调函数这里处理 console.log('doSomethingWithFile: '+ fileContent +'\\n'); }); console.log('我们先去喝杯茶\\n'); 写个Web MVC框架试试
下面我们用node来写一个小玩具:一个Web MVC框架。这个小玩具我称它为n2Mvc,它的代码结构看起来大概如下:
和hello world一样,我们需要一个http的服务器来处理所有进来的请求:
var http = require('http'), querystring = require(\port || 8080; var server = http.createServer(function(req, res){ var _postData = ''; //on用于添加一个监听函数到一个特定的事件 req.on('data', function(chunk) { _postData += chunk; }) .on('end', function() { req.post = querystring.parse(_postData); handlerRequest(req, res); }); }).listen(port); console.log('Server running at http://127.0.0.1:'+ port +'/'); };
这里定义了一个runServer的方法来启动我们的n2Mvc的服务器。有没注意到runServer前面有个exports?这个exports相当于C#中的publish,在用require导入这个模块的时候,runServer可以被访问到。我们写一个脚本来演示下node的模块导入系统:
//moduleExample.js var myPrivate = '艳照,藏着'; exports.myPublish = '冠西的相机'; this.myPublish2 = 'this也可以哦'; console.log('moduleExample.js loaded \\n'); 执行结果:
从结果中我们可以看出exports和this下的变量在外部导入模块后,可以被外部访问到,而var定义的变量只能在脚本内部访问。 从结果我们还可以看出,第二次require导入moduleExample模块的时候,并没有打印“moduleExample.js loaded”,因为require导入模块的时候,会先从require.cache 中检查模块是否已经加载,如果没有加载,才会从硬盘中查找模块脚本并加载。 require支持相对路径查找模块,例如上面代码中require(‘./moduleExample’)中的“./”就代表在当前目录下查找。如果不是相当路径,例如 require(‘http’),node则会到require.paths中去查找,例如我的系统require.paths为:
当require(‘http’)的时候,node的查找路径为:
1、/home/qleelulu/.node_modules/http 2、/home/qleelulu/.node_modules/http.js 3、/home/qleelulu/.node_modules/http.node 4、/home/qleelulu/.node_modules/http/index.js 5、/home/qleelulu/.node_modules/http/index.node 6、/home/qleelulu/.node_libraries/http 7、/home/qleelulu/.node_libraries/http.js 8、参考前面
再看回前面的代码,http.createServer中的回调函数中的request注册了两个事件,前面提到过node的一个特点是事件驱动的,所以这种事件绑定你会到处看到(想想jQuery的事件绑定?例如$(‘a’).click(fn))。关于node的事件我们在后面再细说。request对象的data事件会在接收客户端post上来的数据时候触发,