Home  >  Article  >  Web Front-end  >  A brief analysis of the Readable object in the Stream module of Node.js_node.js

A brief analysis of the Readable object in the Stream module of Node.js_node.js

WBOY
WBOYOriginal
2016-05-16 15:48:16883browse

I have always been reluctant to talk about nodejs, because from the first time I saw it, I thought its design was really disgusting. But there is no way, the Stream specification has not been popularized yet, and there are indeed many things that rely on the nodejs stream to implement, so I can only hold my nose and bite the bullet and pull it out. This smells and is hard. The nodejs stream object.
Nodejs comes with a module called stream. By introducing it, you can get a set of stream object constructors. Now I only talk about the simplest stream.Readable.
In fact, almost everyone who has used nodejs has come into contact with Readable instances, but they just don’t pay much attention to them. A very typical example. In the http module, we will have req and res objects when processing each request. Req is actually a Readable object. We can read the entity part of the HTTP request in the form of a stream on this req.
So the question is, why is the http module designed in a streaming manner here? Or to ask this question from another dimension is "How does nodejs obtain the content of the POST request?". Students who know how to use search engines can definitely find such an answer easily: listen to the data event to collect data, and merge the collected data in the end event. Yes, this is the solution to this problem. But why is it designed this way? How great would it be to be able to get the POST content directly like PHP? In fact, this design is beneficial. If the data we receive is illegal, I can detect it immediately, respond and disconnect. This can avoid some unnecessary transmission costs. For example, when uploading a picture, maybe the user mistakenly selects a large executable file. We don't need to wait until the file is completely uploaded. We only need a few bytes in the file header to determine whether a file is a picture. Using the stream design here, you can first read out the first few bytes for use.
The data event and end event mentioned above are both Readable events. These two events indicate the receipt of data and the completion of data reception respectively. So in fact, we already know the usage of Readable, but many people don't know that it is a Readable object.
But the above two events are only events for consumers of Readable. How does it push a piece of data internally into the Readable object so that Readable can trigger these events? Then it's the push method. Here is an example that creates a Readable object that streams an incrementing number (babel-node is used here)

import stream from 'stream';

var r = new stream.Readable;

r.on('data', data => {
 console.log(data + '');
});

r.on('end', data => {
 console.log('end');
});

r._read = () => {
 // console.log('before read');
};

void function callee(i) {
 if(i < 10) {
  r.push(i + ''); // 只能传入字符串或 Buffre 对象
 } else {
  r.push(null); // 当输入一个 null 时表示流传输完成,触发 end 事件 
 }
 setTimeout(callee, 500, i + 1);
}(0);

If you look carefully at the above code, you will find a very magical place. This code overrides the _read method. What the hell is this? In fact, I also think this is a pitfall. I won’t complain about this private naming style. Why do I have to override this method to implement it? If this method is not overridden, an exception will be thrown when calling push:

 Error: not implemented
  at Readable._read (_stream_readable.js:464:22)
  at Readable.read (_stream_readable.js:341:10)

The above are the basic usage of Readable objects. But there are more pitfalls to step on. This article is just the simplest introduction to let everyone learn how to create a Readable object that can output data. As for some basic methods such as read, these are also one of the unscientific designs anyway.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn