Node.js初体验
北京交通大学Facemash
在godaddy上查到bjtuface.com还未被注册,加上之前得到的一大堆交大学生照片,便萌生了做一个北京交通大学Facemash的念头,facemsh实现上还是非常简单,便决定使用一种没接触过的技术,最后选择了Node.js。
在写facemash时,出奇的顺利,基本没遇到的什么问题,不到1天便搞定了基本的原型,就是现在这个样子,勉强还是能用的,难道是我太厉害了??
用Node.js必须自己拦截所有url,所以不再像用apache、tomcat的时代,css、js、图片等静态文件也必须自己处理,于是工程中便出现了下面这段奇丑无比的代码:
fs.stat(pathname, function (error, stats) { if (error){ response.writeHead(404, {"Content-Type": "text/plain"}); response.write("404 Not found"); response.end(); return; } switch(path.extname(pathname).toLowerCase()){ case ".js": response.writeHead(200, {"Content-Type": "text/javascript"}); break; case ".jpg": response.writeHead(200, {"Content-Type": "image/jpeg"}); break; //....省略一大串部分 default: response.writeHead(200, {"Content-Type": "application/octet-stream"}); break; } response.write(fs.readFileSync(pathname)); response.end(); });
不过这样也好,对于处理图片等静态文件防盗链、防抓取、下载权限的控制就变得非常简单了。
思维转变
用Node.js最主要的是必须保证代码不让一个请求占据Node主线程太长事件,并且不给其他请求处理的机会。
所以当用Node.js写facemash的时候,我必须一直需要考虑这个动作是否会阻塞其他动作的执行,如果会,则必须换成使异步的方法来处理回调或者使用事件处理器来处理执行。
一个简单例子,比如Facemash中要查询票数前N的学生,以前也许我们会这么写:
function getTopNStudents(sex, num){ var queryStr = "SELECT * FROM student WHERE sex = ? ORDER BY tops desc LIMIT ?"; var results = client.query(queryStr , [sex,num]); return results; }
这种写法在传统的阻塞是编程中非常常见,但在Node.js中最好不要这么写,因为这样会阻塞其他的请求。
通过JavaScript匿名函数,之前的代码可以这样写:
function getTopNStudents(sex, num, callback){ var queryStr = "SELECT * FROM student WHERE sex = ? ORDER BY tops desc LIMIT ?"; client.query(queryStr , [sex,num], function(error, results, fields) { if (error) { throw error; } callback(results); }); }
牛逼一个
经常在http的response中header看到Server : Apache吧,那这次我们也可以正大光明搞一个了:
response.setHeader("Server", "yilee-server NB");
嗯,就这样。。。
最后推荐一本小书《Node入门》,1到2小时就能看完,可以迅速了解Node.js的基本使用和思想。