node.js - 10+错误后如何推送到节点流?
问题描述
我最近拿起了一些旧的流代码(在 8.x 是 LTS 时编写的)并尝试将其更新到 12.x。这导致我处理 ENOENT 文件错误的方式发生了有趣的变化。
这是一个简化:
const { createServer } = require('http')
const { createReadStream } = require('fs')
const PORT = 3000
const server = createServer((req, res) => {
res.writeHead(200, {
'Content-Type': 'application/json'
})
const stream = createReadStream(`not-here.json`, {encoding: 'utf8'})
stream.on('error', err => {
stream.push(JSON.stringify({data: [1,2,3,4,5]}))
stream.push(null)
})
stream.pipe(res)
})
server.listen(PORT)
server.on('listening', () => {
console.log(`Server running at http://localhost:${PORT}/`)
})
在 Node 8 中,上面的代码可以正常工作。我能够拦截错误,向流中写入一些内容并让它正常关闭。
在节点 10+(测试 10、12 和 13)中,当我的错误回调被调用时,流已经被销毁。我无法在流中推送新内容并为客户端优雅地处理错误。
这是一个有意的改变吗,我仍然可以以一种很好的方式为克林特处理这个错误吗?
解决方案
一种可能。自己打开文件,只使用已成功打开的文件创建流。这将允许您在进入混乱的流错误处理机制之前处理 ENOENT(或打开文件时的任何其他错误)。流架构似乎与错误中止最为一致,而不是通过一些替代行为进行恢复。
const { createServer } = require('http');
const fs = require('fs');
const PORT = 3000;
const server = createServer((req, res) => {
res.writeHead(200, {'Content-Type': 'application/json'});
fs.open('not-here.json', {encoding: 'utf8'}, (err, fd) => {
if (err) {
// send alternative response here
res.end(JSON.stringify({data: [1,2,3,4,5]}));
} else {
const stream = fs.createReadStream(null, {fd, encoding: 'utf8'});
stream.pipe(res);
}
});
});
server.listen(PORT);
server.on('listening', () => {
console.log(`Server running at http://localhost:${PORT}/`)
});
您还可以尝试在您的流上使用autoDestroy
orautoClose
选项,看看是否有任何这些标志将允许流仍然打开以便您将数据推送到其中,即使文件创建了打开或读取错误。这些标志上的文档不是很完整,因此需要结合编程实验和研究代码来查看它们是否可以被操纵以在流出错后仍将数据添加到流中。
推荐阅读
- latex - 更改位置以在同一级别获取图形和方程 - RMarkdown / .tex
- javascript - 在javascript中出现循环的情况下如何处理firebase ref?
- python - Python速成课程外星人入侵运动
- php - 在 PHP 中删除和重命名
- c - 为什么 linux 内核中的 bitops 性能比我的慢?
- r - 通过向量自回归模型预测多元数据
- c# - 检测导航事件 blazor webassembly
- pandas - KeyError:“[索引([...])都没有在[列]中
- css - 如何在css中自动动画文本突出显示?
- python - 当条件匹配时仅使用 Python 中的 csv 包更新单元格值