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. shell之ulimit应该注意的事项

    详细介绍:http://www.cnblogs.com/xiaOt119/archive/2012/06/13/2547930.html ulimit -n 2048 1.这个限制是针对单个程序的限制 ...

  2. AI-认证

    AI-认证 做登录验证 #models.py class Users(models.Model): user=models.CharField(max_length=32) pwd=models.Ch ...

  3. spring cloud 声明式rest客户端feign调用远程http服务

    在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.Feign就是Spring Cloud提供的一种声明式R ...

  4. 史上最简单的 SpringCloud 教程 | 第一篇: 服务的注册与发现(Eureka)

    一.spring cloud简介 spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选.分布式会话等等.它运 ...

  5. LVS(IPVS)了解

    从来都只是看文章,现在手工作一下. 参考URL: https://blog.csdn.net/langyue919/article/details/80935197 https://www.cnblo ...

  6. [转] mongoose学习笔记(超详细)

    名词解释 Schema: 一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力 Model: 由Schema编译而成的假想(fancy)构造器,具有抽象属性和行为.Model的每一个实例(ins ...

  7. Derive representation formula from Green’s identity

    This article introduces how to derive the representation formula used in BEM from Green's identity. ...

  8. Web Deploy发布网站错误 检查授权和委派设置

    web Deploy发布asp.net网站给我们提供方便,开始配置好了可以方便的发布网站,但是过久就出现无法执行此操作.请与服务器管理员联系,检查授权和委派设置.花了好长时间找到问问所在.现在解决方法 ...

  9. kudu的写数据流程

    写入操作是指需进行插入.更新或删除操作的一组行.需要注意的事项是Kudu强制执行主关键字的唯一性,主关键字是可以更改行的唯一标识符.为了强制执行此约束条件,Kudu必须以不同的方式处理插入和更新操作, ...

  10. PHP把采集抓取网页的html中的的&nbsp;去掉或者分割成数组

    日期:2017/11/6 操作系统:windows 今天抓取网页的时候出现 无法替换,经过多次测试,找到了办法;(注意是从网页上抓取到的) 分割 explode("  ",HTML ...