Node.js

2019-08-12  本文已影响0人  小凡凡520
一、说明
1、Node.js 就是运行在服务端的 JavaScript
2、Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台
3、Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。

如果我们使用PHP来编写后端的代码时,需要Apache 或者 Nginx 的HTTP 服务器,并配上 mod_php5 模块和php-cgi。

二、安装

安装

三、Node.js 应用的组成部分
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('11111Hello World\n');
}).listen(8888);

// 终端打印如下信息
console.log('Server running at http://127.0.0.1:8888/');
四、基本使用

Node.js REPL(交互式解释器)

// 表达式:
$ node
> 1 +4
5

// 使用变量
$ node
> x = 10
10

// 多行表达式
$ node
> do {
... x++;
... console.log("x: " + x);
... } while ( x < 5 );

// 下划线(_)变量
$ node
> var x = 10
undefined
> var y = 20
undefined
> x + y
30
> var sum = _
undefined
> console.log(sum)
30

REPL 命令

快捷键 说明
ctrl + c 退出当前终端
ctrl + c 按下两次 退出 Node REPL
ctrl + d 退出 Node REPL
向上/向下 键 查看输入的历史命令
tab 键 列出当前命令
.help 列出使用命令
.break 退出多行表达式
.clear 退出多行表达式
.save filename 保存当前的 Node REPL 会话到指定文件
.load filename 载入当前 Node REPL 会话的文件内容
五、回调

同步

var fs = require('fs');
var data = fs.readFileSync('/Users/chen_fan/Desktop/mmm.rtf');

console.log(data.toString());

异步

var fs = require('fs');
fs.readFile("/Users/chen_fan/Desktop/mmm.rtf",function (err,data) {
    if (err) return;
    console.log(data.toString());
    console.log('2');
})
console.log('1');
六、事件循环

1、Node.js 是单进程单线程应用程序,但是因为 V8 引擎提供的异步执行回调接口,通过这些接口可以处理大量的并发,所以性能非常高
2、Node.js 几乎每一个 API 都是支持回调函数的。
3、Node.js 基本上所有的事件机制都是用设计模式中观察者模式实现
4、Node.js 单线程类似进入一个while(true)的事件循环,直到没有事件观察者退出,每个异步事件都生成一个事件观察者,如果有事件发生就调用该回调函数

事件驱动程序

1、Node.js 使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。
2、当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户
3、这个模型非常高效可扩展性非常强,因为webserver一直接受请求而不等待任何读写操作。(这也被称之为非阻塞式IO或者事件驱动IO)
在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数。
var events = require('events');
var eventEmitter = new  events.EventEmitter();

var connectHandle = function connected() {
    console.log("连接成功");

    eventEmitter.emit('data_received');
}

eventEmitter.on('connection',connectHandle);

eventEmitter.on('data_received',function() {
    console.log("数据接收成功");
})

eventEmitter.emit("connection");

console.log('完成')
var EventEmitter = require('events').EventEmitter;
var event = new EventEmitter();
event.on('some_event',function () {
  console.log('事件触发');
});
setTimeout(function () {
  event.emit('some_event');
});
var events = require('events');
var emitter =  new events.EventEmitter();
emitter.on('some_event',function (v1, v2) {
  console.log(v1 + v2);
});
emitter.on('some_event',function (v1, v2) {
  console.log(v1,v2);
});
emitter.emit('some_event',1,2);
var events = require('events');
var emitter = new events.EventEmitter();

var call = function() {
    console.log('add');
};

emitter.addListener('ss',call);

emitter.removeListener('ss',call);

emitter.emit('ss');
var events = require('events');
var emitter = new events.EventEmitter();

var listener1 = function () {
    console.log('test1');
};
var listener2 = function () {
    console.log('test2');
};

emitter.addListener('test',listener1);
emitter.on('test',listener2);

console.log(emitter.listenerCount('test'));

emitter.emit('test');
七、缓冲区
const buf = Buffer.from('chenfan','ascii');
console.log(buf.toString('hex'));
console.log(buf.toString('base64'));
编码 说明
ascii 仅支持 7 位 ASCII 数据。如果设置去掉高位的话,这种编码是非常快的
utf8 多字节编码的 Unicode 字符。许多网页和其他文档格式都使用 UTF-8
utf16le 2 或 4 个字节,小字节序编码的 Unicode 字符。支持代理对(U+10000 至 U+10FFFF)
ucs2 utf16le 的别名
base64 Base64 编码
latin1 一种把 Buffer 编码成一字节编码的字符串的方式
binary latin1 的别名
hex 将每个字节编码为两个十六进制字符
// 创建一个长度为 10、且用 0 填充的 Buffer。
const buf1 = Buffer.alloc(10);

// 创建一个长度为 10、且用 0x1 填充的 Buffer。 
const buf2 = Buffer.alloc(10, 1);

// 创建一个长度为 10、且未初始化的 Buffer。
// 这个方法比调用 Buffer.alloc() 更快,
// 但返回的 Buffer 实例可能包含旧数据,
// 因此需要使用 fill() 或 write() 重写。
const buf3 = Buffer.allocUnsafe(10);

// 创建一个包含 [0x1, 0x2, 0x3] 的 Buffer。
const buf4 = Buffer.from([1, 2, 3]);

// 创建一个包含 UTF-8 字节 [0x74, 0xc3, 0xa9, 0x73, 0x74] 的 Buffer。
const buf5 = Buffer.from('tést');

// 创建一个包含 Latin-1 字节 [0x74, 0xe9, 0x73, 0x74] 的 Buffer。
const buf6 = Buffer.from('tést', 'latin1');
buf1.write('123');
buf1.toString('utf8')
八、流

读数据

var fs = require('fs');
var data = '';

var readerStream = fs.createReadStream('/Users/chen_fan/Desktop/HH.h')
readerStream.setEncoding('UTF-8');

readerStream.on('data',function (chunk) {
    data += chunk;
});
readerStream.on('end',function () {
    console.log(data);
});
readerStream.on('error',function (err) {
    console.log(err.stack);
});

写数据

var fs = require('fs');
var data = 'test';
var writeStream = fs.createWriteStream('/Users/chen_fan/Desktop/mmm.rtf');
writeStream.write(data,'utf8');
writeStream.end();

writeStream.on('finish',function () {
    console.log('ok');
});
writeStream.on('error',function (err) {
    console.log(err.stack);
});

管道流

var fs = require('fs');
var readStream = fs.createReadStream('/Users/chen_fan/Desktop/mmm.rtf');
var writeStream = fs.createWriteStream('/Users/chen_fan/Desktop/m1.rtf');

readStream.pipe(writeStream);

链式流

var fs = require("fs");
var zlib = require('zlib');

// 压缩 input.txt 文件为 input.txt.gz
fs.createReadStream('input.txt')
  .pipe(zlib.createGzip())
  .pipe(fs.createWriteStream('input.txt.gz'));
  
console.log("文件压缩完成。");
var fs = require("fs");
var zlib = require('zlib');

// 解压 input.txt.gz 文件为 input.txt
fs.createReadStream('input.txt.gz')
  .pipe(zlib.createGunzip())
  .pipe(fs.createWriteStream('input.txt'));
  
console.log("文件解压完成。");
九、模块系统

接口

exports.world = function() {
    console.log('Hello World');
};

exports.hh = function () {
    console.log('test');
}

var hello = require('./hello');
hello.hh();

模块

//hello.js
function Hello() {
    var name;
    this.setName = function(thyName) {
        name = thyName;
    };
    this.sayHello = function() {
        console.log('Hello ' + name);
    };
};
module.exports = Hello;

var Hello = require('./hello');
var hello = new Hello();
hello.setName('chenfan');
hello.sayHello();
十、函数

普通函数

function say(word) {
    console.log(word)
};

function test(some, value) {
    some(value);
};

test(say,'chenfan');

匿名函数

function test(some, value) {
    some(value);
}

test(function (word) {
    console.log(word)
},'chenfan');
var http = require('http');

http.createServer(function (request, response) {
    response.writeHead(200,{'Content-Type':'text/plain'});
    response.write('chenfan');
    response.end();
}).listen(8888);
var http = require('http');

function onRequest(request,response){
    response.writeHead(200,{'Content-Type':'text/plain'});
    response.write('chenfan');
    response.end();
}

http.createServer(onRequest).listen(8888);
十一、路由
// server.js
var http = require("http");
var url = require("url");
 
function start() {
  function onRequest(request, response) {
    var pathname = url.parse(request.url).pathname;
    console.log("Request for " + pathname + " received.");
    response.writeHead(200, {"Content-Type": "text/plain"});
    response.write("Hello World");
    response.end();
  }
 
  http.createServer(onRequest).listen(8888);
  console.log("Server has started.");
}
 
exports.start = start;
// router.js
function route(pathname) {
  console.log("About to route a request for " + pathname);
}
 
exports.route = route;
// main.js
var server = require("./server");
var router = require("./router");
 
server.start(router.route);
十二、常用工具
var util = require('util'); 
function Base() { 
    this.name = 'base'; 
    this.base = 1991; 
    this.sayHello = function() { 
    console.log('Hello ' + this.name); 
    }; 
} 
Base.prototype.showName = function() { 
    console.log(this.name);
}; 
function Sub() { 
    this.name = 'sub'; 
} 
util.inherits(Sub, Base); 
var objBase = new Base(); 
objBase.showName(); 
objBase.sayHello(); 
console.log(objBase); 
var objSub = new Sub(); 
objSub.showName(); 
//objSub.sayHello(); 
console.log(objSub);
var util = require('util'); 
function Person() { 
    this.name = 'byvoid'; 
    this.toString = function() { 
    return this.name; 
    }; 
} 
var obj = new Person(); 
console.log(util.inspect(obj)); 
console.log(util.inspect(obj, true)); 
var util = require('util');

util.isArray([])
  // true
util.isArray(new Array)
  // true
util.isArray({})
  // false
var util = require('util');

util.isRegExp(/some regexp/)
  // true
util.isRegExp(new RegExp('another regexp'))
  // true
util.isRegExp({})
  // false
var util = require('util');

util.isDate(new Date())
  // true
util.isDate(Date())
  // false (without 'new' returns a String)
util.isDate({})
  // false
var util = require('util');

util.isError(new Error())
  // true
util.isError(new TypeError())
  // true
util.isError({ name: 'Error', message: 'an error occurred' })
  // false
十三、文件系统

读取文件

var fs = require("fs");

// 异步读取
fs.readFile('input.txt', function (err, data) {
   if (err) {
       return console.error(err);
   }
   console.log("异步读取: " + data.toString());
});

// 同步读取
var data = fs.readFileSync('input.txt');
console.log("同步读取: " + data.toString());

console.log("程序执行完毕。");

打开文件

var fs = require("fs");

// 异步打开文件
console.log("准备打开文件!");
fs.open('input.txt', 'r+', function(err, fd) {
   if (err) {
       return console.error(err);
   }
  console.log("文件打开成功!");     
});
flag 说明
r 以读取模式打开文件。如果文件不存在抛出异常
r+ 以读写模式打开文件。如果文件不存在抛出异常
rs 以同步的方式读取文件
rs+ 以同步的方式读取和写入文件
w 以写入模式打开文件,如果文件不存在则创建
wx 类似 'w',但是如果文件路径存在,则文件写入失败
w+ 以读写模式打开文件,如果文件不存在则创建
wx+ 类似 'w+', 但是如果文件路径存在,则文件读写失败
a 以追加模式打开文件,如果文件不存在则创建
ax 类似 'a', 但是如果文件路径存在,则文件追加失败
a+ 以读取追加模式打开文件,如果文件不存在则创建
ax+ 类似 'a+', 但是如果文件路径存在,则文件读取追加失败

获取文件信息

var fs = require('fs');

fs.stat('/Users/liuht/code/itbilu/demo/fs.js', function (err, stats) {
    console.log(stats.isFile());         //true
})
十四、GET / POST
var http = require('http');
var url = require('url');
var util = require('util');

http.createServer(function(req, res){
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end(util.inspect(url.parse(req.url,true)));

}).listen(3000);
var http = require('http');
var url = require('url');
var util = require('util');

http.createServer(function(req, res){
    res.writeHead(200, {'Content-Type': 'text/plain'});

    // 解析 url 参数
    var params = url.parse(req.url, true).query;
    res.write("网站名:" + params.name);
    res.write("\n");
    res.write("网站 URL:" + params.url);
    res.end();

}).listen(3000);
var http = require('http');
var querystring = require('querystring');

var postHTML =
    '<html><head><meta charset="utf-8"><title>菜鸟教程 Node.js 实例</title></head>' +
    '<body>' +
    '<form method="post">' +
    '网站名: <input name="name1"><br>' +
    '网站 URL: <input name="url1"><br>' +
    '<input type="submit">' +
    '</form>' +
    '</body></html>';

http.createServer(function (req, res) {
    var body = "";
    req.on('data', function (chunk) {
        body += chunk;
    });
    req.on('end', function () {
        // 解析参数
        body = querystring.parse(body);
        // 设置响应头部信息及编码
        res.writeHead(200, {'Content-Type': 'text/html; charset=utf8'});

        if(body.name1 && body.url1) { // 输出提交的数据
            res.write("网站名:" + body.name1);
            res.write("<br>");
            res.write("网站 URL:" + body.url1);
        } else {  // 输出表单
            res.write(postHTML);
        }
        res.end();
    });
}).listen(3000);
上一篇下一篇

猜你喜欢

热点阅读