我正在尝试逐行读取和处理文件。我想使用 try / catch 异步模式来做到这一点。下面是一个直接从 NodeJS 文档中提取的关于如何使用 readline 模块的示例。
const { once } = require('events');
const { createReadStream } = require('fs');
const { createInterface } = require('readline');
(async function processLineByLine() {
try {
const rl = createInterface({
input: createReadStream('big-file.txt'),
crlfDelay: Infinity
});
rl.on('line', (line) => {
// Process the line.
});
await once(rl, 'close');
console.log('File processed.');
} catch (err) {
console.error(err);
}
})();
await once
部分让我陷入了我认为的循环。如果在解析行时遇到错误,我想做什么:
rl.on('line', (line) => {
try {
// Process the line. maybe error from parsing?
JSON.parse(line)
} catch ( error ) {
throw new Error("error while attempting to process json.")
}
});
是否可以访问外部 try / catch 块中新抛出的错误,例如:
console.log('File processed.');
} catch (err) {
console.error(err);
// should see "error while attempting to process json."
}
})();
到目前为止,firebase 函数在没有到达外部 try / catch 块的情况下就崩溃了。我尝试将错误事件侦听器添加到 readline 流中,例如:
rl.on("error", () => { // throw error here })
没有成功。
答案 0 :(得分:1)
try/catch 只捕获同步错误。所以它不会从 rl.on()
内部捕获任何东西。执行 await once()
只是在执行 console.log('File processed.');
之前等待流 rl,但 try{}catch(e){}
已经执行,因此无法捕获任何错误。
rl.on('error', () => {}
只会从 rl 流本身捕获错误,因此即使在 createReadStream('big-file.txt')
处发生错误,它也不会被捕获(并且由于它是异步的,最终的 catch(e) 获胜)两者都没有抓住)。
要捕获 rl.on('line ....'
中发生的任何错误,解决方案之一是拒绝该错误。 async/await 函数中被拒绝的错误将像在同步流中一样使用 catch()。
一个例子
async function processLineByLine() {
try{
async function run() {
const rs = createReadStream(__filename)
// otherwise createReadStream() err are not handled
rs.on('error', () => {
console.log('HandleReadStreanErr')
})
const rl = createInterface({
input: rs,
crlfDelay: Infinity
})
return new Promise((resolve, reject) => {
rl.on('line', (line) => {
try {
throw new Error("error while attempting to process json.")
resolve(console.log(line.toString()))
} catch(e) {
reject(e)
}
})
})
// handle specificaly the rl stream error
rl.on('error', () => console.log('errr rl stream'))
await once(rl, 'close');
console.log('File processed.');
}
// await the overall execution for the catch() to wait
await run()
} catch(e) {
// only rejected err reach here or the one happening synchronously
console.error('eeeeeee')
}
}
processLineByLine()
我个人喜欢在每个错误发生的地方处理它们。但是有些人喜欢用 err 处理程序在一个地方处理它们。在这种情况下,我们可以用一个 promise 来包装整个执行
async function processLineByLine() {
try{
async function run() {
return new Promise(async (resolve, reject) => {
const rs = createReadStream('khg.jk')
rs.on('error', () => {
reject('HandleReadStreanErr')
})
const rl = createInterface({
input: rs,
crlfDelay: Infinity
})
rl.on('line', (line) => {
try {
// uncomment following err
// throw new Error("error while attempting to process json.")
resolve(console.log(line.toString()))
} catch(e) {
reject(e)
}
})
rl.on('error', () => reject('errr rl stream'))
await once(rl, 'close');
console.log('File processed.');
})
}
await run()
} catch(e) {
console.error('set error handler: ', e)
}
}
processLineByLine()