使用 Javascript 创建后端(7):NodeJS 事件和流

事件

Node.js 内核的大部分内容都是围绕惯用的事件驱动异步架构构建的,其中某些类型的对象(称为“发射器”)会发出事件,从而引发“侦听器”函数调用。

以下示例展示了一个简单的 EventEmitter,其中有一个“侦听器”,例如,当发生销售时,就会发生此事件

1
2
3
4
5
6
7
8
9
const EventEmitter = require("events");

const myEmitter = new EventEmitter();

myEmitter.on("newSale", () => {
console.log("A new sale occur");
});

myEmitter.emit("newSale");

eventEmitter.on() 方法用于注册一个“监听器”,而 eventEmitter.emit() 方法用于触发事件。

当事件被触发时,函数回调的内容将被执行

1
console.log("A new sale occur");

将参数传递给侦听器

eventEmitter.emit() 方法允许将任意一组参数传递给“侦听器”函数

1
2
3
4
5
6
7
8
9
const EventEmitter = require("events");

const myEmitter = new EventEmitter();

myEmitter.on("newSale", (total) => {
console.log(`A new sale occur total of: ${price}`);
});

myEmitter.emit("newSale", 599.99);

Node.js 服务器与 eventEmitter 配合使用

现在我们了解了 Node.js 事件。我们能够更好地理解 Node.js 服务器对象的逻辑。

1
2
3
4
5
6
7
8
9
10
11
12
const server = http.createServer();

// Create an event called "request"
server.on("request", (req, res) => {
// Execute this code when the "request" event is trigger
res.end("Request received");
});

// this will loop and wait for events
server.listen(5000, "127.0.0.1", () => {
console.log("Waiting for request");
});

什么是流?

流用于逐段(块)处理(读取和写入)数据,而无需完成整个读写操作,也无需将所有数据保存在内存中。

YoutubeNetflix 就是流的很好例子。你无需等待视频完全加载。该过程是逐段(块)完成的。因此,即使尚未下载整个文件,你也可以开始观看媒体。

Node.js 中,有“可读”流和“可写”流。可读流可以是读取的文件或对数据的 http 请求。

可写流与可读流相反,例如 http 响应或要发送的文件

以下是读取大型数据文件的示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const fs = require("fs");
const server = require("http").createServer();

server.on("request", () => {
// No need to load the entire file to memory
// fs.readFile('data.txt', (err, data) => {
// if (err) console.log(err)
// res.end(data);
// })

// Create a Readable Streams
const readable = fs.createReadStream("data.txt");

// Pipe the Stream chunk to a writable Stream
readable.pipe(res);
});

readable.pipe() 方法将“可写”流附加到“可读”流,它会自动将其切换为流动模式并将其所有数据传输到附加的“可写”流。数据流将自动管理,以便目标“可写”流不会被更快的“可读”流淹没。


相关文章: