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. Microsoft Visual Studio Community 2017 修改新建项目的默认位置

    IDE: Microsoft Visual Studio Community 2017 15.5.2 通过修改默认的设置,在下一次新建项目时,就可以节省一些不必要的操作. 菜单:工具 > 选项, ...

  2. eclipse创建动态maven项目

    需求表均同springmvc案例 此处只是使用maven 注意,以下所有需要建立在你的eclipse等已经集成配置好了maven了,说白了就是新建项目的时候已经可以找到maven了 没有的话需要安装m ...

  3. 去掉A标签的点击选中边框

    非IE a:focus { outline:none; }

  4. LOCK TABLES 和 UNLOCK TABLES

    MySQLdump的时LOCK TABLES 和 UNLOCK TABLES 在mysqldump后的数据中会发现有 LOCK TABLES tables_name WRITE;和结尾处有 UNLOC ...

  5. windows server 2012 R2 远程桌面授权模式尚未配置

    windows server 2012 R2 远程桌面授权模式尚未配置,远程桌面服务将在120天内停止工作.如何破解这个宽限期,目前企业7位协议号码均不包含2012 R2以上授权. 那么只能蛋疼的“破 ...

  6. linux dig 命令使用方法

    ref:https://www.imooc.com/article/26971?block_id=tuijian_wz dig 命令主要用来从 DNS 域名服务器查询主机地址信息. 查询单个域名的 D ...

  7. 交换机的vlan文章

    https://blog.csdn.net/standmyground/article/details/3933364 大家知道,交换机会把广播报文(目的mac地址全1的报文)和未知单播报文从所有端口 ...

  8. webpack学习笔记--配置output

    Output output  配置如何输出最终想要的代码. output  是一个  object ,里面包含一系列配置项,下面分别介绍它们. filename output.filename  配置 ...

  9. [转] whistle--全新的跨平台web调试工具

    whistle是基于Node实现的跨平台web调试代理工具,类似的工具有Windows平台上的Fiddler+Willow,基于Java实现的Charles,及公司同事基于Node实现的Livepoo ...

  10. [转] mongodb下载、安装、配置与使用

    记得在管理员模式下运行CMD,否则服务将启动失败. 详细图解,记录 win7 64 安装mongo数据库的过程.安装的版本是 MongoDB-win32-x86_64-2008plus-ssl-3.4 ...