Node.js 应用是由哪几部分组成的:html
- 引入 required 模块:咱们可使用 require 指令来载入 Node.js 模块。
- 建立服务器:服务器能够监听客户端的请求,相似于 Apache 、Nginx 等 HTTP 服务器。
- 接收请求与响应请求: 服务器很容易建立,客户端可使用浏览器或终端发送 HTTP 请求,服务器接收请求后返回响应数据。
建立简单Node.js 应用示例
步骤一:引入 required 模块node
var http = require("http");
步骤二:建立服务器web
var http = require('http'); http.createServer(function (request, response) { // 发送 HTTP 头部 // HTTP 状态值: 200 : OK // 内容类型: text/plain response.writeHead(200, {'Content-Type': 'text/plain'}); // 发送响应数据 "Hello World" response.end('Hello World\n'); }).listen(8888); // 终端打印以下信息 console.log('Server running at http://127.0.0.1:8888/');
步骤三:使用 node 命令执行以上的代码:正则表达式
node server.js Server running at http://127.0.0.1:8888/
步骤四:打开浏览器访问 http://127.0.0.1:8888/,你会看到一个写着 "Hello World"的网页。
分析Node.js 的 HTTP 服务器:设计模式
- 第一行请求(require)Node.js 自带的 http 模块,而且把它赋值给 http 变量。
- 接下来咱们调用 http 模块提供的函数: createServer 。这个函数会返回 一个对象,这个对象有一个叫作 listen 的方法,这个方法有一个数值参数, 指定这个 HTTP 服务器监听的端口号。
Node.js REPL(交互式解释器)
Node 自带了交互式解释器,能够执行如下任务:数组
- 读取 - 读取用户输入,解析输入了Javascript 数据结构并存储在内存中。
- 执行 - 执行输入的数据结构
- 打印 - 输出结果
- 循环 - 循环操做以上步骤直到用户两次按下 ctrl-c 按钮退出。
Node 的交互式解释器能够很好的调试 Javascript 代码。浏览器
REPL 命令
ctrl + c - 退出当前终端。
ctrl + c 按下两次 - 退出 Node REPL。
ctrl + d - 退出 Node REPL.
向上/向下 键 - 查看输入的历史命令
tab 键 - 列出当前命令缓存
.help - 列出使用命令 .break - 退出多行表达式 .clear - 退出多行表达式 .save filename - 保存当前的 Node REPL 会话到指定文件 .load filename - 载入当前 Node REPL 会话的文件内容。 按下两次 ctrl + c 键就能退出 REPL
Node.js 回调函数服务器
- 阻塞代码
建立一个文件 input.txt ,内容自定义。
建立 main.js 文件, 代码以下:
var fs = require("fs"); var data = fs.readFileSync('input.txt'); console.log(data.toString()); console.log("程序执行结束!");
- 非阻塞代码
建立一个文件 input.txt ,内容自定义。
建立 main.js 文件, 代码以下:
var fs = require("fs"); fs.readFile('input.txt', function (err, data) { if (err) return console.error(err); console.log(data.toString()); }); console.log("程序执行结束!");
第一个实例(阻塞)在文件读取完后才执行完程序。 第二个实例(非阻塞)不须要等待文件读取完,这样就能够在读取文件时同时执行接下来的代码,大大提升了程序的性能。阻塞是按顺序执行的,而非阻塞是不须要按顺序的,因此若是须要处理回调函数的参数,咱们就须要写在回调函数内。数据结构
Node.js 事件循环
- Node.js 是单进程单线程应用程序,可是由于 V8 引擎提供的异步执行回调接口,经过这些接口能够处理大量的并发,因此性能很是高。
- Node.js 几乎每个 API 都是支持回调函数的。
- Node.js 基本上全部的事件机制都是用设计模式中观察者模式实现。
- Node.js 单线程相似进入一个while(true)的事件循环,直到没有事件观察者退出,每一个异步事件都生成一个事件观察者,若是有事件发生就调用该回调函数.
Node.js EventEmitter
EventEmitter 类
events 模块只提供了一个对象: events.EventEmitter。EventEmitter 的核心就是***事件触发与事件监听器功能的封装***。能够经过require(“events”);来访问该模块。
// 引入 events 模块 var events = require('events'); // 建立 eventEmitter 对象 var eventEmitter = new events.EventEmitter();
Node.js Buffer(缓冲区)
JavaScript 语言自身只有字符串数据类型,没有二进制数据类型。但在处理像TCP流或文件流时,必须使用到二进制数据。所以在 Node.js中,定义了一个 Buffer 类,该类用来***建立一个专门存放二进制数据的缓存区***。一个 Buffer 相似于一个整数数组,它对应于 V8 堆内存以外的一块原始内存。
Node.js Stream(流)
Stream 是一个抽象接口,Node 中有不少对象实现了这个接口。例如,对http 服务器发起请求的request 对象就是一个 Stream,还有stdout(标准输出)。Node.js,Stream 有四种流类型:
Readable - 可读操做。
Writable - 可写操做。
Duplex - 可读可写操做.
Transform - 操做被写入数据,而后读出结果。
全部的 Stream 对象都是 EventEmitter 的实例。经常使用的事件有:
data - 当有数据可读时触发。
end - 没有更多的数据可读时触发。
error - 在接收和写入过程当中发生错误时触发。
finish - 全部数据已被写入到底层系统时触发。
Node.js模块系统
一个 Node.js 文件就是一个模块,这个文件多是JavaScript 代码、JSON 或者编译过的C/C++ 扩展。
//hello.js 模块 function Hello() { var name; this.setName = function(thyName) { name = thyName; }; this.sayHello = function() { console.log('Hello ' + name); }; }; module.exports = Hello; //main.js 调用hello.js模块(hello.js和node.js是在两个不一样的js文件中) var Hello = require('./hello'); hello = new Hello(); hello.setName('BYVoid'); hello.sayHello();
Node.js 函数
在JavaScript中,一个函数能够做为另外一个函数的参数。咱们能够先定义一个函数,而后传递,也能够在传递参数的地方直接定义函数。
Node.js中函数的使用与Javascript相似。
//把 say 函数做为execute函数的第一个变量进行了传递 function say(word) { console.log(word); } function execute(someFunction, value) { someFunction(value); } execute(say, "Hello");
匿名函数
咱们能够把一个函数做为变量传递。可是咱们不必定要绕这个"先定义,再传递"的圈子,咱们能够直接在另外一个函数的括号中定义和传递这个函数:
//execute 接受第一个参数的地方直接定义了咱们准备传递给 execute 的函数。用这种方式,咱们甚至不用给这个函数起名字,这也是为何它被叫作匿名函数 。 function execute(someFunction, value) { someFunction(value); } execute(function(word){ console.log(word) }, "Hello");
函数传递是如何让HTTP服务器工做的
//咱们向 createServer 函数传递了一个匿名函数。 var http = require("http"); http.createServer(function(request, response) { response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello World"); response.end(); }).listen(8888);
Node.js 全局对象
在浏览器 JavaScript 中,一般 window 是全局对象, 而 Node.js 中的全局对象是 global
- __filename 表示当前正在执行的脚本的文件名。它将输出文件所在位置的绝对路径,且和命令行参数所指定的文件名不必定相同。
- __dirname 表示当前执行脚本所在的目录。
- setTimeout(cb, ms) 全局函数在指定的毫秒(ms)数后执行指定函数(cb)。:setTimeout() 只执行一次指定函数。返回一个表明定时器的句柄值。
-clearTimeout( t ) 全局函数用于中止一个以前经过 setTimeout() 建立的定时器。 参数 t 是经过 setTimeout() 函数建立的定时器。- setInterval(cb, ms) 全局函数在指定的毫秒(ms)数后执行指定函数(cb)。返回一个表明定时器的句柄值。可使用 clearInterval(t) 函数来清除定时器。setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。
- console 用于提供控制台标准输出
- process 是一个全局变量,即 global 对象的属性。它用于描述当前Node.js 进程状态的对象,提供了一个与操做系统的简单接口。
Node.js 经常使用工具
- util.inherits(constructor, superConstructor)是一个实现对象间原型继承 的函数。仅仅继承了原型中定义的函数,而构造函数内部创造的属 性和 函数都没有继承。
- util.inspect(object,[showHidden],[depth],[colors])是一个将任意对象转换 为字符串的方法,一般用于调试和错误输出。
- util.isArray(object)若是给定的参数 “object” 是一个数组返回true,不然返回false。
- util.isRegExp(object)若是给定的参数 “object” 是一个正则表达式返回true,不然返回false。
- util.isDate(object)若是给定的参数 “object” 是一个日期返回true,不然返回false。
- util.isError(object)若是给定的参数 “object” 是一个错误对象返回true,不然返回false。
Node.js 文件系统
异步的 fs.readFile() 和同步的 fs.readFileSync()。
- 异步模式下打开文件:fs.open(path, flags[, mode], callback)
- 异步模式下获取文件信息:fs.stat(path, callback)
- 异步模式下写入文件:fs.writeFile(file, data[, options], callback)
- 异步模式下读取文件:fs.read(fd, buffer, offset, length, position, callback)
- 异步模式下关闭文件:fs.close(fd, callback)
- 异步模式下截取文件:fs.ftruncate(fd, len, callback)
- 删除文件:fs.unlink(path, callback)
- 建立目录:fs.mkdir(path[, mode], callback)
- 读取目录:fs.readdir(path, callback)
- 删除目录:fs.rmdir(path, callback)
使用 Node 建立 Web 服务器
var http = require('http'); var fs = require('fs'); var url = require('url'); // 建立服务器 http.createServer( function (request, response) { // 解析请求,包括文件名 var pathname = url.parse(request.url).pathname; // 输出请求的文件名 console.log("Request for " + pathname + " received."); // 从文件系统中读取请求的文件内容 fs.readFile(pathname.substr(1), function (err, data) { if (err) { console.log(err); // HTTP 状态码: 404 : NOT FOUND // Content Type: text/plain response.writeHead(404, {'Content-Type': 'text/html'}); }else{ // HTTP 状态码: 200 : OK // Content Type: text/plain response.writeHead(200, {'Content-Type': 'text/html'}); // 响应文件内容 response.write(data.toString()); index.html 文件 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>菜鸟教程(runoob.com)</title> </head> <body> <h1>个人第一个标题</h1> <p>个人第一个段落。</p> </body> </html> } // 发送响应数据 response.end(); }); }).listen(8080); // 控制台会输出如下信息 console.log('Server running at http://127.0.0.1:8080/');
使用 Node 建立 Web 客户端
Node 建立 Web 客户端须要引入 http 模块,建立 client.js 文件,代码以下所示:
var http = require('http'); // 用于请求的选项 var options = { host: 'localhost', port: '8080', path: '/index.html' }; // 处理响应的回调函数 var callback = function(response){ // 不断更新数据 var body = ''; response.on('data', function(data) { body += data; }); response.on('end', function() { // 数据接收完成 console.log(body); }); } // 向服务端发送请求 var req = http.request(options, callback); req.end();
新开一个终端,执行 client.js 文件,输出结果以下:
$ node client.js <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>菜鸟教程(runoob.com)</title> </head> <body> <h1>个人第一个标题</h1> <p>个人第一个段落。</p> </body> </html>