天天看点

Node.js入门学习笔记

<code>1</code>

<code>Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. 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.</code>

Google Chrome浏览器基于V8的,它是一个开源的JavaScript引擎,能够编译和执行JavaScript代码,在执行速度上有很大的优势。使用Node.js能够很容易地构建快速、可扩展的网络应程序,它使用了事件驱动、非阻塞I/O模型实现,具有轻量、高效的特点,适合于构建运行在分布地设备之上的数据密集型实时应用程序。

下面通过参考各种资料,从各个方面,概括地总结一下Node.js,是我们对Node.js有一个直观的了解:

使用JavaScript运行于服务端的平台上,自然继承了JavaScript语言的一些特性;

Node.js基于单线程、基于非阻塞I/O模型实现;

适合于数据密集型应用,不适用于计算密集型类的应用(如算法等);

通过使用回调函数,来避免同步地等待I/O操作完成;

Node.js非核心模块非常多,质量可能参差不齐(使用别人贡献的模块,要有承担风险的准备);

因为简单,开发Node.js应用程序效率很高;

调试相对困难,调试工具可能没有其他一些比较成熟的语言(如Java、C++等)的好用;

Node.js基于事件驱动架构,events模块是Node.js最核心的模块。

我学习Node.js使用的工具及其环境配置,如下表所示:

<b>工具/环境</b>

<b>版本</b>

<b>功能</b>

Node.js

0.10.28

Node.js平台

CentOS

6.4

操作系统环境

npm

1.4.9

Node包管理器(Node Package Manager)

Python

2.6.6

Node.js依赖环境(Linux系统下)

Eclipse

Kepler Service Release 2

Node.js调试工具

安装配置

安装步骤,如下所示:

<code>cd /usr/local</code>

<code>2</code>

<code>3</code>

<code>sudo tar xvzf node-v0.10.28-linux-x64.tar.gz</code>

<code>4</code>

<code>sudo ln -s /usr/local/node-v0.10.28-linux-x64 /usr/local/node</code>

<code>5</code>

<code>sudo chown -R shirdrn:shirdrn /usr/local/node*</code>

配置内容:

<code>vi ~/.bashrc</code>

<code>export PATH=$PATH:/usr/local/node/bin</code>

<code>. ~/.bashrc</code>

Node包管理器(npm)

和Python等语言一样,在Node.js中可以使用npm来管理package,常用的命令,如下所示:

<b>命令语法</b>

<b>说明</b>

<b>示例</b>

npm -l

显示npm命令的用法信息

npm install &lt;pkg&gt;

安装包(package)

npm install express

npm install &lt;pkg@version&gt;

安装指定版本的包

npm install [email protected]

npm ls

显示已经安装的包

npm uninstall &lt;pkg&gt;

卸载已经安装的包

npm uninstall express

npm update [pkg]

更新包

npm update或npm update express

npm version

查看npm版本号

npm version或npm -v

npm list

当前目录下已安装的包

npm list -g

当前系统下已经安装的包

npm view &lt;pkg&gt;

查看某个包的信息

npm view express

npm view &lt;pkg&gt; version

查看某个包的版本号

npm view express version

npm view &lt;pkg&gt; dependencies

查看某个包的依赖

npm view express dependencies

npm outdated

查看安装哪些包有新版本发布

npm publish &lt;tarball&gt;

发布包

npm publish mynodejs.tar

npm unpublish &lt;project&gt;[@&lt;version&gt;]

取消发布包

npm unpublish [email protected]

npm init

初始化包(产生package.json)

npm tag &lt;project&gt;@&lt;version&gt; [&lt;tag&gt;]

打tag

npm tag [email protected] stable

使用上面的命令可以方便地管理Node.js包。

node工具

使用node工具运行Node.js脚本非常容易,语法格式如下所示:

<code>node [options] [ -e script | script.js ] [arguments]</code>

有三种执行方式:

运行脚本

比如,运行脚本debug.js,执行如下命令即可:

<code>node debug.js</code>

运行代码

如果,想要直接在命令执行代码段,可以使用-e选项,例如:

<code>node -e</code><code>'console.log("hello")'</code><code>;</code>

其中-e选项后面是一个代码的字符串,他会转换成JavaScript代码在Node.js运行时环境执行,类似eval函数,将执行字符串中的代码。

REPL模式运行

可以直接根据输入node命令,然后回车,根据前导提示符,输入命令执行,一般用来测试比较直观。

调试Node.js代码

可以使用Eclipse开发工具,安装Chrome Developer插件:

<a href="http://chromedevtools.googlecode.com/svn/update/dev/">http://chromedevtools.googlecode.com/svn/update/dev/</a>

这个是在线安装地址。

例如,我们在Eclipse中新建一个debug.js文件,代码如下所示:

<code>// say hello example</code>

<code>var</code> <code>customer =</code><code>'shirdrn'</code><code>;</code>

<code>var</code> <code>f =</code><code>function</code><code>(name) {</code>

<code></code><code>console.log(</code><code>'Hello, '</code> <code>+ name +</code><code>'!'</code><code>);</code>

<code>}</code>

<code>6</code>

<code>f(customer);</code>

然后,在Shell终端启动调试:

<code>node --debug-brk=9222 /home/shirdrn/nodejs/debug.js</code>

接着,可以在Eclipse中对debug.js的代码设置断点,执行Debug As =&gt; Debug Configurations =&gt; 选择Standalone V8 VM,创建一个调试配置,然后可以调试运行,在断点处查看变量的值。

编程实践

使用核心模块events

events模块是Node.js最核心的模块,通过使用该模块,可以了解Node.js的事件机制。下面代码是注册2个事件:一个是解析命令行传入参数的parseCommand事件,另一个是执行Shell命令的executeCommand事件。当脚本启动执行时,发射一个parseCommand事件,把命令行传递的参数传递给该事件函数,解析参数构造Linux下Shell命令行完成后,会发射一个executeCommand事件,去执行这个Shell命令。

实现代码,如下所示:

<code>01</code>

<code>#!/usr/bin/env node</code>

<code>02</code>

<code>03</code>

<code>var</code> <code>process = require(</code><code>'process'</code><code>);</code>

<code>04</code>

<code>var</code> <code>taskShell = require(</code><code>'task-shell'</code><code>);</code>

<code>05</code>

<code>var</code> <code>events = require(</code><code>'events'</code><code>);</code>

<code>06</code>

<code>var</code> <code>bash =</code><code>'/bin/bash'</code><code>;</code>

<code>07</code>

<code>08</code>

<code>// create event emitter</code>

<code>09</code>

<code>var</code> <code>emitter =</code><code>new</code> <code>events.EventEmitter();</code>

<code>10</code>

<code>// register event: 'parseCommand'</code>

<code>11</code>

<code>emitter.on(</code><code>'parseCommand'</code><code>,</code><code>function</code><code>(argv) {</code>

<code>12</code>

<code></code><code>var</code> <code>shell =</code><code>''</code><code>;</code>

<code>13</code>

<code></code><code>console.log(</code><code>'argv.length='</code> <code>+ argv.length);</code>

<code>14</code>

<code></code><code>if</code><code>(argv.length &gt;= 2) {</code>

<code>15</code>

<code></code><code>for</code><code>(</code><code>var</code> <code>i=2; i&lt;argv.length; i++) {</code>

<code>16</code>

<code></code><code>shell +=</code><code>' '</code> <code>+ argv[i];</code>

<code>17</code>

<code></code><code>console.log(</code><code>'shell='</code> <code>+ shell);</code>

<code>18</code>

<code></code><code>}</code>

<code>19</code>

<code>20</code>

<code></code><code>console.log(</code><code>'Parsed shell cmd: '</code> <code>+ shell);</code>

<code>21</code>

<code></code><code>// emit</code>

<code>22</code>

<code></code><code>emitter.emit(</code><code>'executeCommand'</code><code>, shell);</code>

<code>23</code>

<code>});</code>

<code>24</code>

<code>25</code>

<code>//register event: 'executeCommand'</code>

<code>26</code>

<code>emitter.on(</code><code>'executeCommand'</code><code>,</code><code>function</code><code>(shellCmd) {</code>

<code>27</code>

<code></code><code>console.log(</code><code>'Execute shell cmd: '</code> <code>+ shellCmd);</code>

<code>28</code>

<code></code><code>if</code><code>(shellCmd !=</code><code>''</code><code>) {</code>

<code>29</code>

<code></code><code>shellCmd = bash +</code><code>' '</code> <code>+ shellCmd;</code>

<code>30</code>

<code></code><code>var</code> <code>shell =</code><code>new</code> <code>taskShell();</code>

<code>31</code>

<code></code><code>shell.run([], {command : shellCmd}, console);</code>

<code>32</code>

<code></code><code>console.log(</code><code>'Shell cmd executed.'</code><code>);</code>

<code>33</code>

<code>34</code>

<code>35</code>

<code>36</code>

<code>console.log(</code><code>'Passed cmd line: '</code> <code>+ process.argv);</code>

<code>37</code>

<code>emitter.emit(</code><code>'parseCommand'</code><code>, process.argv);</code>

创建一个HTTP服务器

<code>var</code> <code>port = 8080;</code>

<code>var</code> <code>host =</code><code>'192.168.1.115'</code><code>;</code>

<code>console.log(</code><code>'Confiugre: host='</code> <code>+ host +</code><code>', port='</code> <code>+ port);</code>

<code>var</code> <code>http = require(</code><code>'http'</code><code>);</code>

<code>var</code> <code>server = http.createServer(</code><code>function</code><code>(req, res) {</code>

<code></code><code>res.writeHead(200, {</code><code>'Content-Type'</code> <code>:</code><code>'text/plain'</code><code>});</code>

<code></code><code>res.end(</code><code>'Welcome to our site!!!'</code><code>);</code>

<code>console.log(</code><code>'Server created: '</code> <code>+ server);</code>

<code>server.listen(port, host);</code>

在运行前,首先要安装http模块:

<code>npm install http</code>

然后运行脚本(debughttp.js):

<code>node debughttp.js</code>

使用express框架创建HTTP服务器

<code>var</code> <code>express = require(</code><code>'express'</code><code>);</code>

<code>var</code> <code>app = express();</code>

<code>app.use(</code><code>function</code><code>(req, res, next) {</code>

<code></code><code>console.log(</code><code>'%s : %s'</code><code>, req.method, req.url);</code>

<code></code><code>next();</code>

<code></code><code>res.send(200, {</code><code>'hit'</code> <code>:</code><code>'www.shiyanjun.cn'</code><code>});</code>

<code>app.listen(8080);</code>

文件读写

<code>var</code> <code>fs = require(</code><code>'fs'</code><code>);</code>

<code>var</code> <code>file =</code><code>'/etc/passwd'</code><code>;</code>

<code>var</code> <code>encoding =</code><code>'UTF-8'</code><code>;</code>

<code>fs.readFile(file, encoding,</code><code>function</code><code>(err, data) {</code>

<code></code><code>if</code><code>(err) {</code>

<code></code><code>console.error(err);</code>

<code></code><code>}</code><code>else</code> <code>{</code>

<code></code><code>console.log(data);</code>

使用socket.io、socket.io-client、process、util模块

下面实现的脚本,是一个服务端和客户端简单会话的逻辑,脚本名称为endpoint.js,首先需要安装socket.io、socket.io-client、process这三个模块。

下面代码执行,可以通过从命令传递选项参数,选择启动服务器,还是连接到服务器,代码实现如下所示:

<code>var</code> <code>util = require(</code><code>'util'</code><code>);</code>

<code>var</code> <code>startServer =</code><code>function</code><code>() {</code>

<code></code><code>var</code> <code>http = require(</code><code>'http'</code><code>);</code>

<code></code><code>var</code> <code>server = http.Server();</code>

<code></code><code>var</code> <code>io = require(</code><code>'socket.io'</code><code>)(server);</code>

<code></code><code>io.on(</code><code>'connection'</code><code>,</code><code>function</code><code>(socket) {</code>

<code></code><code>console.log(</code><code>'Connected!'</code><code>);</code>

<code></code><code>// emit version infomation</code>

<code></code><code>socket.emit(</code><code>'welcome'</code><code>, {</code><code>'version'</code> <code>:</code><code>'3.5.2'</code><code>,</code><code>'token'</code> <code>:</code><code>'32jfds456FDSOwewA219bMqx4lPsz2'</code><code>});</code>

<code></code><code>socket.on(</code><code>'report'</code><code>,</code><code>function</code><code>(data) {</code>

<code></code><code>console.log(</code><code>'Reported data: '</code> <code>+ util.inspect(data));</code>

<code></code><code>// do something</code>

<code></code><code>console.log(</code><code>'Computed!'</code><code>);</code>

<code></code><code>});</code>

<code></code><code>socket.on(</code><code>'close'</code><code>,</code><code>function</code><code>() {</code>

<code></code><code>console.log(</code><code>'Closed!'</code><code>);</code>

<code></code>

<code></code><code>console.log(</code><code>'Start server.'</code><code>);</code>

<code></code><code>server.listen(port, host);</code>

<code>};</code>

<code>var</code> <code>startClient =</code><code>function</code><code>() {</code>

<code></code><code>var</code> <code>client = require(</code><code>'socket.io-client'</code><code>);</code>

<code></code><code>socket.on(</code><code>'welcome'</code><code>,</code><code>function</code><code>(data){</code>

<code></code><code>console.log(</code><code>'Get welcome info from server: '</code> <code>+ util.inspect(data));</code>

<code></code><code>var</code> <code>version = data[</code><code>'version'</code><code>];</code>

<code></code><code>var</code> <code>token = data[</code><code>'token'</code><code>];</code>

<code></code><code>console.log(</code><code>'version='</code> <code>+ version +</code><code>', token='</code> <code>+ token);</code>

<code>38</code>

<code></code><code>var</code> <code>reportData = {</code><code>'alive'</code> <code>: [</code><code>'node-01'</code><code>,</code><code>'node-06'</code><code>,</code><code>'node-03'</code><code>],</code><code>'dead'</code> <code>: [</code><code>'node-8'</code><code>]};</code>

<code>39</code>

<code></code><code>console.log(</code><code>'Report data: '</code> <code>+ util.inspect(reportData));</code>

<code>40</code>

<code></code><code>socket.emit(</code><code>'report'</code><code>, reportData);</code>

<code>41</code>

<code></code><code>socket.emit(</code><code>'close'</code><code>);</code>

<code>42</code>

<code>43</code>

<code>44</code>

<code>45</code>

<code>46</code>

<code>var</code> <code>argv = process.argv;</code>

<code>47</code>

<code>console.log(</code><code>'Passed arguments: '</code> <code>+ argv);</code>

<code>48</code>

<code>49</code>

<code>var</code> <code>option = argv[2];</code>

<code>50</code>

<code>if</code><code>(</code><code>'server'</code> <code>== option) {</code>

<code>51</code>

<code></code><code>startServer();</code>

<code>52</code>

<code>}</code><code>else</code> <code>if</code><code>(</code><code>'client'</code> <code>== option) {</code>

<code>53</code>

<code></code><code>startClient();</code>

<code>54</code>

<code>}</code><code>else</code> <code>{</code>

<code>55</code>

<code></code><code>console.error(</code><code>'Unknown augment: '</code> <code>+ option +</code><code>'!'</code><code>);</code>

<code>56</code>

启动服务器,执行如下命令行:

<code>node endpoint.js server</code>

启动连接服务器,执行如下命令行:

<code>node endpoint.js client</code>

使用mysql模块连接MySQL数据库

首先要安装mysql、dateformat(格式化日期)模块:

<code>npm install mysql</code>

<code>npm install dateformat</code>

下面是使用Node.js操作MySQL的代码实现:

<code>var</code> <code>mysql = require(</code><code>'mysql'</code><code>);</code>

<code>var</code> <code>dateFormat = require(</code><code>'dateformat'</code><code>);</code>

<code>var</code> <code>config = {</code>

<code></code><code>'host'</code> <code>:</code><code>'192.168.1.105'</code><code>,</code>

<code></code><code>'port'</code> <code>:</code><code>'3306'</code><code>,</code>

<code></code><code>'user'</code> <code>:</code><code>'shirdrn'</code><code>,</code>

<code></code><code>'password'</code> <code>:</code><code>'shiyanjun'</code>

<code>var</code> <code>connect =</code><code>function</code><code>() {</code>

<code></code><code>var</code> <code>connection = mysql.createConnection(config);</code>

<code></code><code>if</code><code>(connection) {</code>

<code></code><code>console.log(</code><code>'Succeed to connected: '</code> <code>+ util.inspect(connection));</code>

<code></code><code>throw</code> <code>new</code> <code>Error(</code><code>'Fail to connect MySQL database!'</code><code>);</code>

<code></code><code>return</code> <code>connection;</code>

<code>var</code> <code>query =</code><code>function</code><code>(sql, callback) {</code>

<code></code><code>// connect to MySQL</code>

<code></code><code>try</code> <code>{</code>

<code></code><code>var</code> <code>connection = connect();</code>

<code></code><code>}</code><code>catch</code><code>(err) {</code>

<code></code><code>console.error(util.inspect(err));</code>

<code></code><code>throw</code> <code>err;</code>

<code></code><code>// execute SQL queries</code>

<code></code><code>connection.query(sql, callback);</code>

<code></code><code>connection.end();</code>

<code></code><code>console.log(</code><code>'Connection closed!'</code><code>);</code>

<code>// query example</code>

<code>var</code> <code>querySQL =</code><code>'SELECT id, host, port, updated_at FROM domain_db.traffic_proxy LIMIT 0,10'</code><code>;</code>

<code>query(querySQL,</code><code>function</code><code>(err, rows, fields) {</code>

<code></code><code>for</code><code>(</code><code>var</code> <code>i=0; i&lt;rows.length; i++) {</code>

<code></code><code>var</code> <code>row = rows[i];</code>

<code></code><code>var</code> <code>host = row[</code><code>'host'</code><code>];</code>

<code></code><code>var</code> <code>port = row[</code><code>'port'</code><code>];</code>

<code></code><code>var</code> <code>updatedAt = dateFormat(row[</code><code>'updated_at'</code><code>],</code><code>'yyyy-MM-dd hh:mm:ss'</code><code>);</code>

<code></code><code>console.log(</code><code>'Record: host='</code> <code>+ host +</code><code>', port='</code> <code>+ port +</code><code>', updatedAt='</code> <code>+ updatedAt);</code>

上面代码,从MySQL数据库中的一个表中查询数据,然后打印出来。

想进一步深入理解Node.js,可以参考相关文档,主要包括Node.js提供的一些特性,如继承(还有JavaScript具有的一些特性)。Node.js还有很多的模块,通过学习来开发自己Node.js应用程序。

继续阅读