As long as you have played with nodejs, you must have come into contact with Writable. The res parameter in the request callback parameter of the http module is a Writable object. We often write a bunch of things to it and finally call the end method, right? These are all behaviors of Writable.
The Writable object we create manually is given to the user, so the write and end methods are called by the user. As a provider, how do we know what operations our Writable objects have been performed by users? Just guess this API, I will guess a certain event first. But no! Like Readable, it also has to override a method to listen for operations. The following is an example of creating a Writable to allow users to write content into it and monitor what the user writes (based on babel-node):
import stream from 'stream'; var w = new stream.Writable; w._write = (buffer, enc, next) => { console.log(buffer + ''); next(); // 触发「写入完成」 }; w.on('finish', () => { console.log('finish'); }); void function callee(i) { if(i < 10) { w.write(i + '', 'utf-8', () => { // 写入完成 }); } else { w.end(); } setTimeout(callee, 10, i + 1); }(0);
Same as Readable's _read, if the above _write is not overwritten, an exception will be thrown:
Error: not implemented at Writable._write (_stream_writable.js:430:6) at doWrite (_stream_writable.js:301:12)
In addition, write is designed as an asynchronous method, and its third parameter can be passed in the completion callback. The so-called completion is that in the implementation function _write, the next parameter is called. There is a reason why write is designed to be asynchronous. If it is executed synchronously, sequence errors may occur when we need to handle some asynchronous transactions in the _write method. For example, the write operation of a disk file is asynchronous. If we ignore this asynchronous operation when writing a file, then if the previous write operation is blocked and has not been completed, the current write operation may be executed first. So we should reasonably call next in _write (must be called, otherwise it will be stuck in wait and unable to continue writing).
Finally, when the data writing is completed, the finish event will be triggered, which means that the end method is called by the user. If you are doing a file writing operation, you should close the file at this time.