NodeJS:等待跳过 Catch 块并退出函数。为什么?
NodeJS: Await Skips Catch Block and Exits Function. Why?
这是我的第一个问题,请给我反馈。
有问题的文件是一个非常大的文件,所以我正在考虑使用异步读取。
预期行为:
成功:“await”将导致代码执行阻塞,直到文件被读取。
错误:即使 await 失败,任何错误都应该被 catch 块捕获。 console.log() 应该表明它正在被捕获。
观察到:await失败,catch块被完全跳过,继续执行Main的下一行。跳过整个异步函数。在调试器中,我可以看到 result 中的正确输出只是一瞬间出现,然后直接从函数中退出。
谁能告诉我为什么会这样,我该如何解决?
据我了解,如果发生异常,catch 块将总是 捕获它。请尽可能详细和清晰地解释,我仍在努力掌握 NodeJS 语言。
被注释掉的行是我想做同样任务的另一种方式。它也有同样的问题。当我也有一个时,它甚至跳过了一个“finally”块。
此外,Main 中的“c”变量是调试器中的 'pending' 承诺。
最后,这段代码的总体目的是解析一个JSON文本形式的文件。这只是更大文件的 MVCE。
const fs = require('fs');
const util = require('util');
async function uploadFile(fileName) {
try {
const readFile = util.promisify(fs.readFile);
result = await readFile(fileName, 'utf-8');
//result = await fs.readFileSync(fileName, 'utf-8');
jsonObj = JSON5.parse(result);
}
catch (err) {
console.log(err);
}
}
function Main() {
fileName = './Diagnostics_Data_Analysis/AddingToDynamoDB/diag.txt';
var c = uploadFile(fileName);
console.log("Done");
process.exit(0);
}
Main();
await
不阻塞。它暂停执行本地函数和那个函数,然后立即 returns 一个承诺。调用者需要使用该承诺来知道操作何时完成。在文件读取完成之前,您实际上是在调用 process.exit()
。这里发生的事情是这样的:
- 您的代码执行
await readFile(fileName, 'utf-8');
并且 uploadFile()
函数被挂起并立即 returns 一个承诺。
console.log("Done")
运行
process.exit(0)
运行。
- 文件尚未读取,您的程序已退出。
相反,您可以这样做:
async function Main() {
const fileName = './Diagnostics_Data_Analysis/AddingToDynamoDB/diag.txt';
const c = await uploadFile(fileName);
console.log("Done");
process.exit(0);
}
这将等待 uploadFile()
函数在调用 process.exit(0)
之前实际通知完成。
P.S。 Nodejs 现在已经内置了 fs
库的承诺版本,因此您可以使用 fs.promises.readFile()
而不必制作自己的承诺版本。
这是我的第一个问题,请给我反馈。
有问题的文件是一个非常大的文件,所以我正在考虑使用异步读取。
预期行为:
成功:“await”将导致代码执行阻塞,直到文件被读取。
错误:即使 await 失败,任何错误都应该被 catch 块捕获。 console.log() 应该表明它正在被捕获。
观察到:await失败,catch块被完全跳过,继续执行Main的下一行。跳过整个异步函数。在调试器中,我可以看到 result 中的正确输出只是一瞬间出现,然后直接从函数中退出。
谁能告诉我为什么会这样,我该如何解决? 据我了解,如果发生异常,catch 块将总是 捕获它。请尽可能详细和清晰地解释,我仍在努力掌握 NodeJS 语言。
被注释掉的行是我想做同样任务的另一种方式。它也有同样的问题。当我也有一个时,它甚至跳过了一个“finally”块。
此外,Main 中的“c”变量是调试器中的 'pending' 承诺。
最后,这段代码的总体目的是解析一个JSON文本形式的文件。这只是更大文件的 MVCE。
const fs = require('fs');
const util = require('util');
async function uploadFile(fileName) {
try {
const readFile = util.promisify(fs.readFile);
result = await readFile(fileName, 'utf-8');
//result = await fs.readFileSync(fileName, 'utf-8');
jsonObj = JSON5.parse(result);
}
catch (err) {
console.log(err);
}
}
function Main() {
fileName = './Diagnostics_Data_Analysis/AddingToDynamoDB/diag.txt';
var c = uploadFile(fileName);
console.log("Done");
process.exit(0);
}
Main();
await
不阻塞。它暂停执行本地函数和那个函数,然后立即 returns 一个承诺。调用者需要使用该承诺来知道操作何时完成。在文件读取完成之前,您实际上是在调用 process.exit()
。这里发生的事情是这样的:
- 您的代码执行
await readFile(fileName, 'utf-8');
并且uploadFile()
函数被挂起并立即 returns 一个承诺。 console.log("Done")
运行process.exit(0)
运行。- 文件尚未读取,您的程序已退出。
相反,您可以这样做:
async function Main() {
const fileName = './Diagnostics_Data_Analysis/AddingToDynamoDB/diag.txt';
const c = await uploadFile(fileName);
console.log("Done");
process.exit(0);
}
这将等待 uploadFile()
函数在调用 process.exit(0)
之前实际通知完成。
P.S。 Nodejs 现在已经内置了 fs
库的承诺版本,因此您可以使用 fs.promises.readFile()
而不必制作自己的承诺版本。