Node.js API 快速入门

一、事件EventEmitter

const EventEmitter = require('events');
class MyEmitter extends EventEmitter{}
const eventEmitter = new MyEmitter();
//设置链接事件监听器
eventEmitter.on('connection', (url) => {
   console.log(`链接 ${url} 成功!`);
   eventEmitter.emit('data_received', '神秘代码');
});
//数据接收监听器
eventEmitter.on('data_received', (data) => {
   console.log(`数据 ${data} 接收成功!`);
});
//触发链接事件
eventEmitter.emit('connection', 'Google');
console.log('任务完成!');
/*链接 Google 成功!
据 神秘代码 接收成功!
任务完成!*/

二、二进制缓存Buffer

JavaScript 语言自身只有字符串数据类型,没有二进制数据类型。

但在处理像TCP流或文件流时,必须使用到二进制数据。因此在 Node.js中,

定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区。

在 Node.js 中,Buffer 类是随 Node 内核一起发布的核心库。

原始数据存储在 Buffer 类的实例中。一个 Buffer 类似于一个整数数组,

但它对应于 V8 堆内存之外的一块原始内存。

//创建一个长度为512,且用0填充的Buffer
let buf = Buffer.alloc(512);
//缓冲区长度
console.log(buf.length);
//向缓冲区写入字符串,默认使用utf-8编码
//返回实际写入的大小,如果缓存区空间不足,只会写入一部分
let len = buf.write('写入了一些东西');
console.log(`写入字节数: ${len}`);
//从缓存区读取数据
console.log(buf.toString('base64', 0, 12)); //5YaZ5YWl5LqG5LiA

三、流Stream

Stream 是一个抽象接口,Node.js,Stream 有四种流类型:

  • Readable - 可读操作

  • Writable - 可写操作

  • Duplex - 可读可写操作

  • Transform - 操作被写入数据,然后读出结果

所有的 Stream 对象都是 EventEmitter 的实例。常用的事件有:

  • data - 当有数据可读时触发。

  • end - 没有更多的数据可读时触发。

  • error - 在接收和写入过程中发生错误时触发。

  • finish - 所有数据已被写入到底层系统时触发。

读取和写入:

const fs = require('fs');
let data = '';
let inputData = 'What\'s the matter with you. Say me something new.';
//创建可读流
let readerStream = fs.createReadStream('sth.txt');
readerStream.setEncoding('UTF8');
//处理流事件
readerStream.on('data', (buf) => {
    data += buf;
});
readerStream.on('end', () => {
    console.log(data);
});
readerStream.on('error', (err) => {
   console.log(err.stack);
});
console.log('读出完毕??????');
/*
程序执行完毕!
I have a orange.*/

let writerStream = fs.createWriteStream('output.txt');
writerStream.write(data, 'UTF8');
//标记文件末尾
writerStream.end();
//处理流事件
writerStream.on('finish', () => {
   console.log('写入完成!');
});
writerStream.on('error', (err) => {
    console.log(err.stack);
});
console.log('写入完毕?????');

/*
读出完毕??????
写入完毕?????
写入完成!
I have a orange.*/

管道流:

管道提供了一个输出流到输入流的机制。通常我们用于从一个流中获取数据并将数据传递到另外一个流中。

const fs = require('fs');
let reader = fs.createReadStream('sth.txt');
//如果没有input.txt会创建
let writer = fs.createWriteStream('input.txt');
//读取sth.txt的内容写入到input.txt中去
reader.pipe(writer);

链式流:

链式是通过连接输出流到另外一个流并创建多个流操作链的机制。链式流一般用于管道操作。

接下来我们就是用管道和链式来压缩和解压文件。创建 compress.js 文件, 代码如下:

const fs = require('fs');
const zlib = require('zlib');

//压缩文件
fs.createReadStream('input.txt')
    .pipe(zlib.createGzip())
    .pipe(fs.createWriteStream('input.txt.gz'));
console.log('文件压缩完成');

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

四、全局对象

在浏览器 JavaScript 中,通常 window 是全局对象, 而 Node.js 中的全局对象是 global,

所有全局变量(除了 global 本身以外)都是 global 对象的属性。

具体API略

五、文件系统---fs模块

Node.js 文件系统(fs 模块)模块中的方法均有异步和同步版本,例如读取文件内容的函数有异步的 fs.readFile()

和同步的 fs.readFileSync()。异步的方法函数最后一个参数为回调函数,回调函数的第一个参数包含了错误信息(error)。

建议大家使用异步方法,比起同步,异步方法性能更高,速度更快,而且没有阻塞。

const fs = require('fs');
console.log('准备写入文件:');
fs.open()
//对同一文件多次使用 fs.writeFile 且不等待回调,是不安全的。
//对于这种情况,建议使用 fs.createWriteStream。
//如果 file 是一个文件描述符,则它不会被自动关闭。
fs.writeFile('input.txt', '被写入文件的内容,可以是string或者是Buffer', (err) => {
    //如果有错误
    if (err) {
        return console.error(err);
    }
    console.log('数据写入成功');
    console.log('准备读取文件');
    //fs.readFile() 函数会缓存整个文件。 为了最小化内存占用,
    // 尽可能优先使用 fs.createReadStream()。
    //如果 path 是一个文件描述符,则它不会被自动关闭。
    fs.readFile('input.txt', (err, data) => {
        if (err) {
            return console.error(err);
        }
        console.log('读取到的数据是:' + data);
    })
});

六、Web模块

Node.js 提供了 http 模块,http 模块主要用于搭建 HTTP 服务端和客户端。

获取get内容:

const http = require('http');
const url = require('url');

http.createServer((req, res) => {
   res.writeHead(200, {'Content-Type': 'text/plain'});
   //解析url参数,获取get中的内容
   let params = url.parse(req.url, true).query;
   res.write(`Name: ${params.name} \n`);
   res.write(`Phone: ${params.phone}`);
   res.end();
}).listen(3000);
//浏览器输入:http://localhost:3000/?name=tang&phone=898989
//浏览器显示:
// Name: tang
//Phone: 898989

获取post内容:

var http = require('http');
var querystring = require('querystring');
http.createServer(function(req, res){
    // 定义了一个post变量,用于暂存请求体的信息
    var post = '';
    // 通过req的data事件监听函数,每当接受到请求体的数据,就累加到post变量中
    req.on('data', function(chunk){
        post += chunk;
    });
    // 在end事件触发后,通过querystring.parse将post解析为真正的POST请求格式,然后向客户端返回。
    req.on('end', function(){
        post = querystring.parse(post);
        res.end(util.inspect(post));
    });
}).listen(3000);

创建web服务器:

const http = require('http');
const url = require('url');
const fs = require('fs');

function controller(req, res) {
    //解析文件名
    let pathName = url.parse(req.url).pathname;
    //输出请求的文件名
    console.log('请求的文件名为:'+ pathName);
    //读取请求的html文件内容
    fs.readFile(pathName.substring(1), (err, data) => {
        if (err) {
            console.error(err);
            res.writeHead(404, {'Content-Type' : 'text/html'});
        } else {
            res.writeHead(200, {'Content-Type' : 'text/html'});
            //响应文件内容
            res.write(data.toString());
        }
        res.end();
    });
}
http.createServer(controller).listen(8099);
console.log('Server running at http://localhost:8099/');

七、Express框架

GET方法:

const express = require('express');
const app = express();

app.use(express.static('public'));
app.get('/', (req, res) => {
    res.sendFile( __dirname + '/' + 'home.html');
});
app.get('/dataBack', (req, res) => {
    let dataBackJSON = {
        "FirstName: " : req.query.firstName,
        "LastName: " : req.query.lastName
    };
    console.log(dataBackJSON);
    res.send(JSON.stringify(dataBackJSON));
});
app.listen(8099, () => {
   console.log('Listening');
});

POST方法:

const express = require('express');
const app = express();
const bodyParser = require('body-parser');

app.use(express.static('public'));

let urlencodedParser = bodyParser.urlencoded({ extended: false });
app.get('/home', (req, res) => {
    res.sendFile(`${__dirname}/home.html`);
});
app.post('/dataBack', urlencodedParser, (req, res) => {
    let data = {
        "FirstName: " : req.body.firstName,
        "LastName: " : req.body.lastName
    };
    console.log(data);
    res.send(JSON.stringify(data));
});

app.listen(8099, () => {
    console.log('Just do it!');
});

文件上传:

const express = require('express');
const app = express();
const fs = require('fs');
const bodyParser = require('body-parser');
const multer  = require('multer');

app.use(express.static('public'));
app.use(multer({ dest: '/tmp/'}).array('image'));

app.get('/home', (req, res) =>{
    res.sendFile( __dirname + "/" + "home.html" );
});

app.post('/upload', (req, res) => {
    let uploadFile = req.files[0];
    console.log(uploadFile);//上传文件的信息
    let desFile = __dirname + '/' + uploadFile.originalname;
    fs.readFile(uploadFile.path, (err, data) => {
       if (err) return console.error(err);
       fs.writeFile(desFile, data, (err) => {
          if (err) return console.error(err);
          let result = {
              "message: " : 'Upload Success!',
              "FileName: " : uploadFile.originalname
          };
          console.log(result);
          res.end(JSON.stringify(result));
       });
    });
});

app.listen(8099, () => {
   console.log(`Listening`);
});

八、 多进程

1.child_process.exec(command[, options], callback)

使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数参数的形式返回。

参数:

command: 字符串,将要运行的命令,参数使用空格隔开。

options: 对象,可以是:

cwd ,字符串,子进程的当前工作目录

env,对象 环境变量键值对

encoding ,字符串,字符编码(默认: 'utf8')

shell ,字符串,将要执行命令的 Shell(默认: 在 UNIX 中为/bin/sh, 在 Windows 中为cmd.exe, Shell 应当能识别 -c开关在 UNIX 中,或 /s         /c 在 Windows 中。 在Windows 中,命令行解析应当能兼容cmd.exe

timeout,数字,超时时间(默认: 0)

maxBuffer,数字, 在 stdout 或 stderr 中允许存在的最大缓冲(二进制),如果超出那么子进程将会被杀死 (默认: 200*1024)

killSignal ,字符串,结束信号(默认:'SIGTERM')

uid,数字,设置用户进程的 ID

gid,数字,设置进程组的 ID

callback回调函数,包含三个参数error, stdout 和 stderr。

该方法方法返回最大的缓冲区,并等待进程结束,一次性返回缓冲区的内容。

const cps = require('child_process');

for (let i = 0; i < 3; i++) {
    let wps = cps.exec('node support.js ' + i, (err, stdout, stderr) => {
        if (err) console.log(err.stack);
        console.log(`standOut: ${stdout}`);
    });
    wps.on('exit', (code) => {
        console.log('子进程已经退出,退出码为:' + code);
    });
}
/*子进程已经退出,退出码为:0
standOut: 进程 0 执行

子进程已经退出,退出码为:0
standOut: 进程 1 执行

子进程已经退出,退出码为:0
standOut: 进程 2 执行*/
console.log(`进程 ${process.argv[2]} 执行`);

2.child_process.spawn(command[, args][, options])

使用指定的命令行参数创建新进程,spawn() 方法返回流 (stdout & stderr),在进程返回大量数据时使用。

进程一旦开始执行时 spawn() 就开始接收响应。

const cps = require('child_process');

for (let i = 0; i < 3; i++) {
    let wps = cps.spawn('node', ['support.js', i]);
    wps.stdout.on('data', (data) => {
        console.log('stdout: ' + data);
    });
    wps.stderr.on('data', (data) => {
        console.log(`stdout: ${data}`);
    });
    wps.on('close', (code) => {
        console.log(`子进程${i}已退出,退出码:${code}`);
    });
}
/*stdout: 进程 0 执行

子进程0已退出,退出码:0
stdout: 进程 1 执行

stdout: 进程 2 执行

子进程1已退出,退出码:0
子进程2已退出,退出码:0*/

Node.js API快速入门的更多相关文章

  1. Node.js web快速入门 -- KoaHub.js

    介绍 KoaHub.js -- 基于 Koa.js 平台的 Node.js web 快速开发框架.可以直接在项目里使用 ES6/7(Generator Function, Class, Async & ...

  2. Node.js web快速入门 -- KoaHub.js组件koa-static-server

    koa-static-server Static file serving middleware for koa with directory, rewrite and index support k ...

  3. Html5 学习系列(五)Canvas绘图API快速入门(1)

    引言:Canvas绘图API快速入门 在接触HTML5的初学者包括我都在很多地方见到非常炫的一些页面,甚至好多学习HTML5的开发者都是冲着Web端的页游去的,那么HTML5那么绚丽的页面效果以及游戏 ...

  4. 引言:Canvas绘图API快速入门

    引言:Canvas绘图API快速入门 在接触HTML5的初学者包括我都在很多地方见到非常炫的一些页面,甚至好多学习HTML5的开发者都是冲着Web端的页游去的,那么HTML5那么绚丽的页面效果以及游戏 ...

  5. Node.js API 初解读(一)

    Node.JS API 初解读 Version: NodeJs v6.2.0 一. Assert 1.简介 Assert模块主要用于断言.如果表达式不符合预期,就抛出一个错误. 该模块用于编写程序的单 ...

  6. Node.js API

    Node.js v4.4.7 Documentation(官方文档) Buffer Prior to the introduction of TypedArray in ECMAScript 2015 ...

  7. KoaHub.js是基于 Koa.js 平台的 Node.js web 快速开发框架

    koahubjs KoaHub.js -- 基于 Koa.js 平台的 Node.js web 快速开发框架.可以直接在项目里使用 ES6/7(Generator Function, Class, A ...

  8. 基于 Koa.js 平台的 Node.js web 快速开发框架KoaHub.js demo 可安装

    KoaHub.js demo KoaHub.js KoaHub.js -- 基于 Koa.js 平台的 Node.js web 快速开发框架.可以直接在项目里使用 ES6/7(Generator Fu ...

  9. KoaHub.js -- 基于 Koa.js 平台的 Node.js web 快速开发框架之koahub-yilianyun

    koahub-yilianyun 微信易联云打印机接口 koahub-yilianyun易联云打印机node接口 Installation $ npm install koahub-yilianyun ...

随机推荐

  1. node.js 的热更新

    1.安装 npm i supervisor -gd 2.运行 supervisor server.js //server.js 是你自己的服务的js文件

  2. Spring声明式事务@Transactional 详解,事务隔离级别和传播行为

    @Transactional注解支持9个属性的设置,这里只讲解其中使用较多的三个属性:readOnly.propagation.isolation.其中propagation属性用来枚举事务的传播行为 ...

  3. httpstatus类的状态有哪些

    HTTP Status Code 常见的状态码: HTTP: Status 200 – 服务器成功返回网页HTTP: Status 404 – 请求的网页不存在HTTP: Status 503 – 服 ...

  4. 微信小程序 this和that详解及简单实例

    微信小程序中,在wx.request({});方法调用成功或者失败之后,有时候会需要获取页面初始化数据data的情况,这个时候,如果使用,this.data来获取,会出现获取不到的情况,调试页面也会报 ...

  5. MySQL 官方 Docker 镜像的使用

    首先是pull image,这里我拉取的是5.6.35: $ sudo docker pull mysql:5.6.35 拉下来以后大可以按照官方的说明无脑启动,但是外部无法访问,所以绑定端口: $ ...

  6. python之https爬虫出现 SSL: CERTIFICATE_VERIFY_FAILED (同时打开fiddler就会出现)

    1.参考 Py 坑之 CERTIFICATE_VERIFY_FAILED Python 升级到 2.7.9 之后引入了一个新特性,当你urllib.urlopen一个 https 的时候,会验证一次 ...

  7. Failed to create Accelerated Display. Please check the display hardware and drivers meet the minimum requirements.

    ArcGIS Runtime for WPF开发中Map设置了属性UseAcceleratedDisplay="True",报错: Sample: LocalMap Error: ...

  8. day3.python字符串格式化

    字符串格式化 注意:若在格式化输出中还需要再加%,需要两个%来代替 方法1:%控制格式化输出 例1: print("I'm %s. I'm %d year old" % ('Vam ...

  9. Ubuntu16.04中nginx除80之外其他端口不能访问

    不废话, 大多数都以为是ufw防火墙的问题. 但我的是因iptables防火墙, 坑死我了. 查了好多也没查到怎么在Ubuntu关闭iptables, 索性直接卸载 apt-get remove ip ...

  10. 2018牛客网暑假ACM多校训练赛(第四场)C Chiaki Sequence Reloaded (组合+计数) 或 数位dp

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round4-C.html 题目传送门 - https://www.no ...