我正在尝试找到在Node.js中过早终止一系列管道流(管道)的正确方法:有时我想在流完成之前优雅地中止流.具体来说,我正在处理大部分objectMode: true和非原生的并行流,但这并不重要.
问题是当我unpipe在管道中时,数据保留在每个流的缓冲区中并被drain编辑.对于大多数中间流(例如/ ),这可能没问题,但是最后一个仍然流向其写目标(例如文件或数据库或套接字或w/e).如果缓冲区包含数百或数千个块需要花费大量时间来消耗,则这可能是有问题的.我希望它立即停止,即不要排水; 为什么浪费周期和内存对数据无关紧要?ReadableTransformWritable
根据我去的路线,我收到"写后结束"错误,或者当流找不到现有管道时发生异常.
什么是优雅地杀死表单中的流管道的正确方法a.pipe(b).pipe(c).pipe(z)?
我提出的解决方案是3步:
unpipe 管道中的每个流以相反的顺序排列Writableend 每个实现的流 Writable一些伪代码说明了整个过程:
var pipeline = [ // define the pipeline
readStream,
transformStream0,
transformStream1,
writeStream
];
// build and start the pipeline
var tmpBuildStream;
pipeline.forEach(function(stream) {
if ( !tmpBuildStream ) {
tmpBuildStream = stream;
continue;
}
tmpBuildStream = lastStream.pipe(stream);
});
// sleep, timeout, event, etc...
// tear down the …Run Code Online (Sandbox Code Playgroud) 在Javascript(Node.js上下文)中,我Function.prototype.bind经常使用:bind允许更改调用上下文并可选地提供其他前置参数.
是否有任何关于附加论点的建议?有几次我遇到了在Node.js中追加而不是prepend的需要,所以我可以坚持它的函数签名模式.
现在是一个半实用和简化的例子; 我正在使用异步模块的eachSeries方法.
首先,一个包装回调的实现(工作,但很长的路):
function func(something,callback) {
async.eachSeries(
[1,2,3],
function iterator(item,asyncCallback) {
// do stuff
asyncCallback(err||null);
},
function finished(err) {
// `callback` expects 2 arguments
// `err` should always be the first arg, null or otherwise
// `something` (unrelated to the async series) should be maintained
callback(err,something);
}
);
};
Run Code Online (Sandbox Code Playgroud)
而现在有点短:
function func(something,callback) {
async.eachSeries(
[1,2,3],
function iterator(item,asyncCallback) {
// do stuff
asyncCallback(err||null);
},
callback.bindAppend(this,something)
// pseudo-equiv: …Run Code Online (Sandbox Code Playgroud) 我有方法,在这个方法中可能会发生致命错误,因为我抓住了这个错误
class a {
function shutDownFunction() {
$error = error_get_last();
if ($error['type'] == 1) {
echo "this is fatal error";
}
}
function terribleFunction () {
register_shutdown_function(array($this,'shutdownFunction'));
// here is code, wich may causes fatal error
}
}
Run Code Online (Sandbox Code Playgroud)
好了,这个理解,但我需要通过参数terribleFunction来shutDownFunction.怎么做到这个?
我试图显示字符í的0xed(237).
String.fromCharCode 产生正确的结果:
String.fromCharCode(0xed); // 'í'
Run Code Online (Sandbox Code Playgroud)
但是,使用时Buffer:
var buf = new Buffer(1);
buf.writeUInt8(0xed,0); // <Buffer ed>
buf.toString('utf8'); // '?', same as buf.toString()
buf.toString('binary'); // 'í'
Run Code Online (Sandbox Code Playgroud)
使用'binary'with Buffer.toString是不赞成的,所以我想避免这种情况.
其次,我还可以预期传入的数据是多字节的(即UTF-8),例如:
String.fromCharCode(0x0512); // ? - correct
var buf = new Buffer(2);
buf.writeUInt16LE(0x0512,0); // <Buffer 12 05>, [0x0512 & 0xff, 0x0512 >> 8]
buf.toString('utf8'); // ? - correct
buf.toString('binary'); // Ô
Run Code Online (Sandbox Code Playgroud)
请注意,这两个示例都不一致.
那么,我错过了什么?我假设我不应该做什么?是String.fromCharCode神奇吗?