Node.js基础入门实例讲解

事件驱动的编程对于初学者来说可能有点儿困难,正是这个原因使得node.js对于初学者来说不是那么容易。但是不要觉得有压力,在今天的这篇教程中,我们将给大家介绍node.js的入门知识,并且讲解为什么node.js会如此的流行。

介绍

在开始介绍node.js之前,你需要了解传统的服务器端应用(PHP,JSP,Ruby,Python)和node.js的区别。

异步编程

如果你了解异步(Asynchronous)编程的话,将会非常简单。 这里的A和Ajax里的”A”是同一个单词。在node.js中每一个方法都是异步的。因此事实上任何一个“阻断”线程的东西都运行在后台。这是大家需要务必了解的。例如,如果你尝试阅读一个文件,你需要指定一个Callback方法来控制阅读操作完成后的动作。

你需要自己处理全部

Node.js提供的是一个环境,这个环境中你需要自己处理所有事情。 所以呢,这里没有缺省的web服务器,或者类似服务器。对于新手来说可能有点恐怖,但是回报也是巨大的,你将得到超棒性能的web应用。一个脚本来处理所有客户端的通信。这很大程度的减少了应用消耗的资源。以下就是一个简单的node.js的例子:

var i, a, b, c, max;
 
max = 1000000000;
 
var d = Date.now();
 
for (i = 0; i < max; i++) {
    a = 1234 + 5678 + i;
    b = 1234 * 5678 + i;
    c = 1234 / 2 + i;
}
 
console.log(Date.now() - d);

类似的PHP代码如下:

$a = null;
$b = null;
$c = null;
$i = null;
$max = 1000000000;
 
$start = microtime(true);
 
for ($i = 0; $i < $max; $i++) {
    $a = 1234 + 5678 + $i;
    $b = 1234 * 5678 + $i;
    $c = 1234 / 2 + $i;
}
 
var_dump(microtime(true) - $start);

现在我们看看性能对比:

循环次数 Node.js PHP
100 2.00 0.14
10’000 3.00 10.53
1’000’000 15.00 1119.24
10’000’000 143.00 10621.46
1’000’000’000 11118.00 1036272.1

大家可以看到,使用PHP在小数据的循环中占有优势,但是对于大数据量的循环,node.js将会比PHP快93%。

模块

node.js使用了模块化的架构体系来简化复杂应用。模块类似于C的类库和pascal中的unit。每一个模块包含了相关主题的一套功能。例如,你可以使用http模块来处理HTTP相关的功能。同时node.js提供了一些核心的类库帮助你访问文件系统中的文件,创建HTTP和TCP/UDP服务器,及其其它相关的实用功能。

包含一个模块非常简单,如果你使用过Dojo的话,你肯定熟悉require方法,如下:

var http = require('http');

require()方法返回指定模块的参考。在这个代码中,一个HTTP模块的参考将保存在http变量中。

在以上代码中,我们传递了模块的名字到require()方法。这是的Node搜索node_module目录来查询http模块,如果没有找到模块,将会到全局模块缓存中查询。你可以指定一个实际的文件,如下:

var myModule = require('./myModule.js');

模块包含了代码片段。模块中的代码大部分是私有的 ,这意味你不能在外部直接访问变量。只能在模块内部访问。当然,你可以使用expose来将变量或者方法倒出模块,这样你可以在模块外部使用,如下:

var PI = Math.PI;
 
exports.area = function (r) {
  return PI * r * r;
};
 
exports.circumference = function (r) {
  return 2 * PI * r;
};

这个代码中,PI是一个私有的模块变量。下面两个方法将给予exports对象创建。这些方法能够在模块外部被访问因为它们基于exports方法。因此,你可以保证area()和circumference()将会按照它们原本的行为来实现操作。

全局变量

node.js基于google的v8 javascript引擎,所以我们需要遵守客户端的最佳实践。例如,我们需要避免将任何内容知道全局变量中。当然,不是任何情况都可以做到的。Node中使用的全局范围是GLOBAL,你可以通过忽略var关键字来定义一个全局变量:

globalVariable = 1;
globalFunction = function () { ... };

安装

在使用Node.js之前,你需要安装它。 安装过程非常简单,如果你使用windows或者OS x,nodejs.org提供了不同操作系统下的安装包,对于Linux来说,你可以使用任何的打包工具。打开你的终端,输入:

sudo apt-get update
sudo apt-get install node

或者:

sudo aptitude update
sudo aptitude install node

Node.js位于sid repositories,你可以添加它们到你的列表里:

sudo echo deb http://ftp.us.debian.org/debian/ sid main > /etc/apt/sources.list.d/sid.list

注意在旧系统中安装sid包可能会破坏你的系统。所以当心,安装完node后请移除/etc/apt/sources.list.d/sid.list

安装新模块

Node.js拥有一个包管理器,叫做Node Package Manager(NPM)。自动随node.js安装,你可以使用NPM来安装模块。执行如下语句:

npm install module_name

不管你使用何种OS,上面语句会安装指定的模块名称

Hello World 应用

很自然,我们第一个Node.js脚本将打印Hello world到控制台。如下:

console.log('Hello World, GBin1!');

我们保存以上脚本为hello.js。打开终端/命令行,找到hello.js,执行如下:

node hello.js

你应该在控制台看到’hello world, GBin1!’字样。

HTTP Server

下面我们开发一个更复杂的应用,当让也不是那么复杂。请先看看如下代码http.js:

// Include http module.
var http = require("http");
 
// Create the server. Function passed as parameter is called on every request made.
// request variable holds all request parameters
// response variable allows you to do anything with response sent to the client.
http.createServer(function (request, response) {
   // Attach listener on end event.
   // This event is called when client sent all data and is waiting for response.
   request.on("end", function () {
      // Write headers to the response.
      // 200 is HTTP status code (this one means success)
      // Second parameter holds header fields in object
      // We are sending plain text, so Content-Type should be text/plain
      response.writeHead(200, {
         'Content-Type': 'text/html'
      });
      // Send data and end response.
      response.end('Welcome to <a href="http://www.gbin1.com">GBin1.com</a>!');
   });
// Listen on the 8080 port.
}).listen(8080);

代码其实并不复杂,你可以看到我们使用response.write()将数据传递到客户端,当然必须在response.end()之前调用。保存代码,然后在控制台执行:

node http.js

打开任何浏览器,输入http://localhost:8080,你可以看到”Welcome to GBin1.com!”出现在页面上。

Node.js基础入门实例讲解

处理URL参数

正如前面我们提到的,我们需要自己处理Node.js中的任何东西,包括处理参数,其实非常简单,如下:

// Include http module, 
var http = require("http"), 
// And url module, which is very helpful in parsing request parameters. 
   url = require("url"); 
 
// Create the server. 
http.createServer(function (request, response) { 
   // Attach listener on end event. 
   request.on('end', function () { 
      // Parse the request for arguments and store them in _get variable. 
      // This function parses the url from request and returns object representation. 
      var _get = url.parse(request.url, true).query; 
      // Write headers to the response. 
      response.writeHead(200, { 
         'Content-Type': 'text/plain'
      }); 
      // Send data and end response. 
      response.end('Here is your data: ' + _get['data']); 
   }); 
// Listen on the 8080 port. 
}).listen(8080);

这个代码使用url模块的parse()方法,来将请求的URL转换为一个对象。返回的对象拥有一个query属性,可以用来取得URL参数。保存这段代码为get.js并且执行:

node get.js

打开浏览器并且输入地址http://localhost:8080/?data=put_gbstring_here。你将看到效果。

写入和读取文件

我们在node.js中使用fs模块来管理文件。使用fs.readFile()和fs.writeFile()方法来读取和写入文件,请看如下代码:

// Include http module,
var http = require("http"),
// And mysql module you've just installed.
   fs = require("fs");
 
// Create the http server.
http.createServer(function (request, response) {
   // Attach listener on end event.
   request.on("end", function () {
      // Read the file.
      fs.readFile("test.txt", 'utf-8', function (error, data) {
         // Write headers.
         response.writeHead(200, {
            'Content-Type': 'text/plain'
         });
         // Increment the number obtained from file.
         data = parseInt(data) + 1;
         // Write incremented number to file.
         fs.writeFile('test.txt', data);
         // End response with some nice message.
         response.end('This page was refreshed ' + data + ' times!');
      });
   });
// Listen on the 8080 port.
}).listen(8080);

将以上代码保存为file.js,然后创建一个test.txt文件到同一个目录下。

代码展示如何使用fs.readFile()和fs.writeFile()。每一次服务器收到一个请求,脚本就会自动添加1,然后写回文件。fs.readFile()方法接受3个参数:文件名称,编码,callback方法。

写入文件,在这个例子中,非常简单。我们不需要等待任何结果,虽然你仍旧处理错误。fs.writeFile()方法接受文件名称和数据作为参数。同时接受第三个和第四个参数(都是可选的)来指定编码和callback方法。运行脚本:

node files.js

打开浏览器,输入http://localhost:8080,刷新页面几次。看看结果好像有bug,这里每次加了2。其实这不是一个错误。每一次你请求这个URL的时候,俩个请求被发送到服务器。第一个请求是浏览器自动请求的 favion.ico。当然第二个请求是我们脚本对应URL(http://localhost:8080)

为了解决这个问题,我们修改代码如下:

// Include http module,
var http = require("http"),
// And mysql module you've just installed.
   fs = require("fs");
 
// Create the http server.
http.createServer(function (request, response) {
   // Attach listener on end event.
   request.on('end', function () {
      // Check if user requests /
      if (request.url == '/') {
         // Read the file.
         fs.readFile('test.txt', 'utf-8', function (error, data) {
            // Write headers.
            response.writeHead(200, {
               'Content-Type': 'text/plain'
            });
            // Increment the number obtained from file.
            data = parseInt(data) + 1;
            // Write incremented number to file.
            fs.writeFile('test.txt', data);
            // End response with some nice message.
            response.end('This page was refreshed ' + data + ' times!');
         });
      } else {
         // Indicate that requested file was not found.
         response.writeHead(404);
         // And end request without sending any data.
         response.end();
      }
   });
// Listen on the 8080 port.
}).listen(8080);

现在看看,结果是不是正确了。

访问Mysql数据库

对于一个正常的服务器端技术,肯定需要有机制来处理数据库操作。为了在node.js中使用数据库,我们需要安装类库,这里我们使用node-mysql。完整的名称是mysql@2.0.0-alpha2(@后面是版本号)。打开你的控制台,导航到你保存脚本的目录,执行如下命令:

npm install mysql@2.0.0-alpha2

这将下载和安装模块,同时创建node_module目录到目前目录中。下面我们看看如何使用代码访问mysql:

// Include http module, 
var http = require('http'), 
// And mysql module you've just installed. 
   mysql = require("mysql"); 
     
// Create the connection. 
// Data is default to new mysql installation and should be changed according to your configuration. 
var connection = mysql.createConnection({ 
   user: "root", 
   password: "", 
   database: "db_name"
}); 
 
// Create the http server. 
http.createServer(function (request, response) { 
   // Attach listener on end event. 
   request.on('end', function () { 
      // Query the database. 
      connection.query('SELECT * FROM your_table;', function (error, rows, fields) { 
         response.writeHead(200, { 
            'Content-Type': 'x-application/json' 
         }); 
         // Send data as JSON string. 
         // Rows variable holds the result of the query. 
         response.end(JSON.stringify(rows)); 
      }); 
   }); 
// Listen on the 8080 port. 
}).listen(8080);

查询数据库非常简单,输入查询语句和callback方法。在一个实际的应用中,你应该检查是否有错误!(一旦有错误,error参数将不会为undefined),并且发送响应代码基于查询成功或者失败,注意我们设定content-type为x-application/json,这是正确的JSON MIME类型。rows参数包含了查询结果,这里我们使用JSON,stringify()方法简单的将rows中的数据转换为JSON结构

保存脚本为mysql.js,执行:

node mysql.js

在浏览器中输入http://localhost:8080,你可以看到要求你下载JSON格式数据文件。

总结

node.js要求你自己处理额外的开发内容,但是回报是更好的性能和健壮的应用。如果你不希望处理底层,你可以选择成熟的框架,例如,Express,这样开发更加简单。

node.js是一个很不错的技术并且非常适合高负荷的应用。并且已经被很多企业证明,例如,微软,eBay和Yahoo。如果你不确认该使用任何服务器,你可以考虑VPS或者云平台。都拥有比较好的价格。 希望大家喜欢这个入门级别的Node.js教程,如果你有任何问题,请在GBin1的浏览版中给我们留言,谢谢!

本文固定链接: http://www.ccsbbs.com.cn/archives/5976.html | 极限手指

该日志由 极限手指 于2013年03月10日发表在 node.js 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: Node.js基础入门实例讲解 | 极限手指

Node.js基础入门实例讲解:等您坐沙发呢!

发表评论

您必须 [ 登录 ] 才能发表留言!