码迷,mamicode.com
首页 > 其他好文 > 详细

mafintosh/end-of-stream

时间:2018-11-07 17:15:50      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:http   not   mod   expect   remove   highlight   with   creates   一起   

https://github.com/mafintosh/end-of-stream

Call a callback when a readable/writable/duplex stream has completed or failed.

 

end-of-stream

A node module that calls a callback when a readable/writable/duplex stream has completed or failed.

就是当一个可读/可写。双工流完成或失败时可以回调的模块,如eos(readableStream,cb)意思就是当将这个回调函数cb与流封装到一起啦,readableStream之后可以进行各种操作,pipe/destroy等,然后相应地触发cb回调函数

npm install end-of-stream

 

Usage

Simply pass a stream and a callback to the eos. Both legacy streams, streams2 and stream3 are supported.

var eos = require(end-of-stream);

eos(readableStream, function(err) {
  // this will be set to the stream instance
    if (err) return console.log(stream had an error or closed early);
    console.log(stream has ended, this === readableStream);//readableStream关闭可读是end,上下文环境this即readableStream
});

eos(writableStream, function(err) {
    if (err) return console.log(stream had an error or closed early);
    console.log(stream has finished, this === writableStream);//writableStream关闭可写是finish
});

eos(duplexStream, function(err) {
    if (err) return console.log(stream had an error or closed early);
    console.log(stream has ended and finished, this === duplexStream);//duplexStream关闭要end和finish
});

eos(duplexStream, {readable:false}, function(err) {
    if (err) return console.log(stream had an error or closed early);
    console.log(stream has finished but might still be readable);//{readable:false}即不end,该duplexStream可能还能读
});

eos(duplexStream, {writable:false}, function(err) {
    if (err) return console.log(stream had an error or closed early);
    console.log(stream has ended but might still be writable);//{writable:false}即不finish,该duplexStream可能还能写
});

eos(readableStream, {error:false}, function(err) {
    // do not treat emit(‘error‘, err) as a end-of-stream
});

 

end-of-stream/index.js

在这里设置是finish后是不可写,end后是不可读

var once = require(once);

var noop = function() {};

var isRequest = function(stream) {
    return stream.setHeader && typeof stream.abort === function;
};

var isChildProcess = function(stream) {
    return stream.stdio && Array.isArray(stream.stdio) && stream.stdio.length === 3
};

var eos = function(stream, opts, callback) {
    if (typeof opts === function) return eos(stream, null, opts);
    if (!opts) opts = {};

    callback = once(callback || noop);

    var ws = stream._writableState;
    var rs = stream._readableState;
    var readable = opts.readable || (opts.readable !== false && stream.readable);
    var writable = opts.writable || (opts.writable !== false && stream.writable);

    var onlegacyfinish = function() {
        if (!stream.writable) onfinish();
    };

    var onfinish = function() {
        writable = false;
        if (!readable) callback.call(stream);
    };

    var onend = function() {
        readable = false;
        if (!writable) callback.call(stream);
    };

    var onexit = function(exitCode) {
        callback.call(stream, exitCode ? new Error(exited with error code:  + exitCode) : null);
    };

    var onerror = function(err) {
        callback.call(stream, err);
    };

    var onclose = function() {
        if (readable && !(rs && rs.ended)) return callback.call(stream, new Error(premature close));
        if (writable && !(ws && ws.ended)) return callback.call(stream, new Error(premature close));
    };

    var onrequest = function() {
        stream.req.on(finish, onfinish);
    };

    if (isRequest(stream)) {
        stream.on(complete, onfinish);
        stream.on(abort, onclose);
        if (stream.req) onrequest();
        else stream.on(request, onrequest);
    } else if (writable && !ws) { // legacy streams
        stream.on(end, onlegacyfinish);
        stream.on(close, onlegacyfinish);
    }

    if (isChildProcess(stream)) stream.on(exit, onexit);
    
//三类事件的监听 stream.on(
end, onend); stream.on(finish, onfinish); if (opts.error !== false) stream.on(error, onerror); stream.on(close, onclose); return function() { stream.removeListener(complete, onfinish);//移除改事件并调用onfinish函数 stream.removeListener(abort, onclose); stream.removeListener(request, onrequest); if (stream.req) stream.req.removeListener(finish, onfinish); stream.removeListener(end, onlegacyfinish); stream.removeListener(close, onlegacyfinish); stream.removeListener(finish, onfinish); stream.removeListener(exit, onexit); stream.removeListener(end, onend); stream.removeListener(error, onerror); stream.removeListener(close, onclose); }; }; module.exports = eos;

所以当调用eos(...)时,基本上就是监听了各式各样的事件,然后返回一个函数。这个函数里面是各类的removeListener,就是将你之前的监听全部移除,并触发相应的事件,运行返回的函数的方法就是eos(...)(),如下面的第四个例子

end-of-stream/test.js
var assert = require(assert);
var eos = require(./index);

var expected = 10;//下面有十个例子
var fs = require(fs);
var cp = require(child_process);//nodejs子进程,看博客
var net = require(net);
var http = require(http);

var ws = fs.createWriteStream(/dev/null);
eos(ws, function(err) {
    expected--;
    assert(!!err);
    assert(this === ws);
    if (!expected) process.exit(0);
});
ws.destroy();//将会触发error和close事件

var rs1 = fs.createReadStream(/dev/urandom);
eos(rs1, function(err) {
    expected--;
    assert(!!err);
    assert(this === rs1);
    if (!expected) process.exit(0);//说明运行成功
});
rs1.destroy();//将会触发error和close事件

var rs2 = fs.createReadStream(__filename);
eos(rs2, function(err) {
    expected--;
    assert.ifError(err);
    assert(this === rs2);
    if (!expected) process.exit(0);
});
rs2.pipe(fs.createWriteStream(/dev/null));

var rs3 = fs.createReadStream(__filename);
eos(rs3, function(err) {
    assert.ifError(err);
    assert(this === rs);
    throw new Error(no go);
})();//运行eos的返回函数,即各个removeListener
rs3.pipe(fs.createWriteStream(/dev/null));

var exec = cp.exec(echo hello world);
eos(exec, function(err) {
    expected--;
    assert.ifError(err);
    assert(this === exec);
    if (!expected) process.exit(0);
});

var spawn = cp.spawn(echo, [hello world]);
eos(spawn, function(err) {
    expected--;
    assert.ifError(err);
    assert(this === spawn);
    if (!expected) process.exit(0);
});

var socket = net.connect(50000);
eos(socket, function(err) {
    expected--;
    assert(!!err);
    assert(this === socket);
    if (!expected) process.exit(0);
});

var server = net.createServer(function(socket) {
    eos(socket, function(err) {
        expected--;
        assert(!!err);
        assert(this === socket);
        if (!expected) process.exit(0);
    });
    socket.destroy();
}).listen(30000, function() {
    var socket = net.connect(30000);
    eos(socket, function(err) {
        expected--;
        assert.ifError(err);
        assert(this === socket);
        if (!expected) process.exit(0);
    });
});

var server2 = http.createServer(function(req, res) {
    eos(res, function(err) {
        expected--;
        assert.ifError(err);
    });
    res.end();
}).listen(function() {
    var port = server2.address().port;
    http.get(http://localhost: + port, function(res) {
        eos(res, function(err) {
            expected--;
            assert.ifError(err);
            server2.close();
        });
        res.resume();
    });
});

setTimeout(function() {
    assert(expected === 0);
    process.exit(0);
}, 1000);
    • process.exit(0)表示成功完成,回调函数中,err将为null;

    • process.exit(非0)表示执行失败,回调函数中,err不为null,err.code就是我们传给exit的数字。

 

mafintosh/end-of-stream

标签:http   not   mod   expect   remove   highlight   with   creates   一起   

原文地址:https://www.cnblogs.com/wanghui-garcia/p/9889215.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!