流消费者的 API
几乎所有的 Node.js 应用程序,无论多么简单,都以某种方式使用流。 以下是在实现 HTTP 服务器的 Node.js 应用程序中使用流的示例:
const http = require('node:http');
const server = http.createServer((req, res) => {
// `req` 是 http.IncomingMessage,它是可读流。
// `res` 是 http.ServerResponse,它是可写流。
let body = '';
// 以 utf8 字符串形式获取数据。
// 如果未设置编码,则将接收缓冲区对象。
req.setEncoding('utf8');
// 一旦添加了监听器,则可读流就会触发 'data' 事件。
req.on('data', (chunk) => {
body += chunk;
});
// 'end' 事件表示已经接收到整个正文。
req.on('end', () => {
try {
const data = JSON.parse(body);
// 给用户回写一些有趣的东西:
res.write(typeof data);
res.end();
} catch (er) {
// 哦哦!糟糕的 json!
res.statusCode = 400;
return res.end(`error: ${er.message}`);
}
});
});
server.listen(1337);
// $ curl localhost:1337 -d "{}"
// object
// $ curl localhost:1337 -d "\"foo\""
// string
// $ curl localhost:1337 -d "not json"
// error: Unexpected token 'o', "not json" is not valid JSON
Writable
流(例如示例中的 res
)暴露了用于将数据写入流的方法,例如 write()
和 end()
。
当数据可从流中读取时,Readable
流使用 EventEmitter
API 来通知应用程序代码。
可以通过多种方式从流中读取可用数据。
Writable
和 Readable
流都以各种方式使用 EventEmitter
API 来传达流的当前状态。
Duplex
和 Transform
流都是 Writable
和 Readable
。
向流中写入数据或从流中消费数据的应用程序不需要直接实现流的接口,并且通常没有理由调用 require('node:stream')
。
希望实现新类型的流的开发者应参考流实现者的 API 章节。
Almost all Node.js applications, no matter how simple, use streams in some manner. The following is an example of using streams in a Node.js application that implements an HTTP server:
const http = require('node:http');
const server = http.createServer((req, res) => {
// `req` is an http.IncomingMessage, which is a readable stream.
// `res` is an http.ServerResponse, which is a writable stream.
let body = '';
// Get the data as utf8 strings.
// If an encoding is not set, Buffer objects will be received.
req.setEncoding('utf8');
// Readable streams emit 'data' events once a listener is added.
req.on('data', (chunk) => {
body += chunk;
});
// The 'end' event indicates that the entire body has been received.
req.on('end', () => {
try {
const data = JSON.parse(body);
// Write back something interesting to the user:
res.write(typeof data);
res.end();
} catch (er) {
// uh oh! bad json!
res.statusCode = 400;
return res.end(`error: ${er.message}`);
}
});
});
server.listen(1337);
// $ curl localhost:1337 -d "{}"
// object
// $ curl localhost:1337 -d "\"foo\""
// string
// $ curl localhost:1337 -d "not json"
// error: Unexpected token 'o', "not json" is not valid JSON
Writable
streams (such as res
in the example) expose methods such as
write()
and end()
that are used to write data onto the stream.
Readable
streams use the EventEmitter
API for notifying application
code when data is available to be read off the stream. That available data can
be read from the stream in multiple ways.
Both Writable
and Readable
streams use the EventEmitter
API in
various ways to communicate the current state of the stream.
Duplex
and Transform
streams are both Writable
and
Readable
.
Applications that are either writing data to or consuming data from a stream
are not required to implement the stream interfaces directly and will generally
have no reason to call require('node:stream')
.
Developers wishing to implement new types of streams should refer to the section API for stream implementers.