4 javascript events stream node.js
有什么区别:
const stream = createReadStream(source).pipe(createWriteStream(destination));
stream.on("error", (error) => {
stream.destroy();
stream.removeListener("close");
reject(error);
});
stream.on("close", () => {
// do something
});
Run Code Online (Sandbox Code Playgroud)
VS:
const writable = createWriteStream(destination);
const readable = createReadStream(source);
readable.on("error", onError);
writable.on("error", onError);
function onError(error) {
readable.destroy();
writable.destroy();
writable.removeListener("close", onClose);
reject(error);
}
Run Code Online (Sandbox Code Playgroud)
如果发生某些错误,我们为什么要手动销毁流?节点不会自动执行此操作?
谢谢.
好吧,有一点,你的第二个例子根本不执行任何管道或数据传输.两者之间唯一的另一个显着区别是,在第一个示例中,您没有将"错误"事件侦听器附加到读取流,这意味着如果在读取数据时发生错误,则不会捕获错误.您不应该删除"关闭"侦听器或销毁流.看起来您正在尝试将文件复制到新位置并使该函数返回Promise.在这种情况下,"关闭"事件是否触发无关紧要,因为Promise只能被解析/拒绝一次.因此,如果"错误"事件触发,那么您的Promise将被拒绝,并且它永远不会被解析,因此没有理由删除"close"侦听器.此外,节点会在发出错误后自动将流标记为已销毁.这应该是你所需要的:
const fs = require('fs')
function copy (source, target) {
return new Promise((resolve, reject) => {
const rs = fs.createReadStream(source)
const ws = fs.createWriteStream(target)
rs.on('error', reject)
ws.on('error', reject)
rs.pipe(ws).on('close', resolve)
})
}
Run Code Online (Sandbox Code Playgroud)
然后你可以这样使用它:
copy('/foo/bar.json', '/baz/qux.json')
.then(() => console.log('copy done'))
Run Code Online (Sandbox Code Playgroud)