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. poj2411 状态压缩-铺地板题型-轮廓线解法(最优)

    解法参考博客https://blog.csdn.net/u013480600/article/details/19569291 一种做法是先打出所有的状态,即满足上下配对的所有可能方案,然后再逐行进行 ...

  2. jQuery核心方法

    1.$(document.body).css( "background", "black" ); 2.$(myForm.elements).hide():隐藏表 ...

  3. AI学习吧

    一:AI学习吧 项目描述 系统使用前后端分离的模式,前端使用vue框架,后端使用restframework实现. 项目需求 公司开发AI学习吧,由于公司需要一款线上学习平台,要开发具有线上视频学习.支 ...

  4. MySQL修改数据表存储引擎的3种方法介绍

    这篇文章主要介绍了MySQL修改数据表存储引擎的3种方法介绍,分别是直接修改.导出导入.创建插入3种方法, 可以参考下   MySQL作为最常用的数据库,经常遇到各种各样的问题.今天要说的就是表存储引 ...

  5. OpenAuth.Net.landv分支之旅开始制作CRM系统

    OpenAuth.Net.landv分支之旅开始制作CRM系统 这个事件的由来是因为没有一个统一的会员卡平台系统,目前需要连接三家酒店会员系统,由于三家酒店使用了三种酒店管理系统,彼此之间的耦合低.三 ...

  6. 下载离线VS2017

    1.下载工具 版本 文件 Visual Studio Enterprise (企业版) vs_enterprise.exe Visual Studio Professional (专业版) vs_pr ...

  7. CentOS升级glibc-2.14

    升级glibc-2.14用到的rpm https://pan.baidu.com/s/1v-Uk579TGM6498cExst6ow 先要安装gcc yum -y install gcc 执行: rp ...

  8. 【BZOJ1095】【ZJOI2007】捉迷藏 [动态点分治]

    题解: 好像还是比较简单的 对每个重心向下一层重心连边 树高是log的 我们对每一层维护两个信息 1.所有节点到上一层重心的距离 2.所有儿子的1堆的堆顶 另外开个总的堆 维护每一层最长+次长 修改是 ...

  9. word/excel/cad中插入二维码

    1.有需求为在word文档中插入二维码,寻访度娘后,大部分人推荐使用QRmaker制作. 2.找寻QRmaker,网上很多都是1.1版本,后来才知道这个版本有问题(对中文支持不好),偶然得到1.3的版 ...

  10. ELK使用2-Kibana使用

    一.创建kibana索引 1.es索引可以在这儿查看 2.kibana创建索引可以在这儿查看(必须es中存在相应的索引才能在kibana中创建) 点击创建然后选择es中存在的索引即可创建相应的索引 3 ...