如何确保仅在 await-function 完成后才执行代码?
How to ensure a code execution only after the await-function is done?
如果我的 Node.js v.13.12 应用程序遇到一些技术问题,我想:
- 在数据库中写入日志消息;
- 使用特定代码退出 Node.js 应用程序。
为了实现这种行为,我使用了以下代码:
const onError = async function onError(error) {
await logger.log("Critical error: " + error);
process.exit(UNCAUGHT_FATAL_EXCEPTION);
}
问题是当我执行上面的代码时,我到达await logger.log(…)
,进去然后立即继续process.exit(UNCAUGHT_FATAL_EXCEPTION)
并执行。
因此,应用程序在写入数据库之前关闭,尽管我希望 await
等到 logger.log(…)
完成。
我的问题:
如何确保process.exit(UNCAUGHT_FATAL_EXCEPTION)
只在logger.log(…)
完成后执行而不使用回调?
更新:
整个 logger.log(…)
代码链:
export const log = async function log(source, severityNum, severityLevel, limitSeverityNum, functionName, message) {
if ((severityNum > LOG_LEVELS.OFF.intLevel) && (severityNum <= limitSeverityNum)) {
await writeLogToDB(source, severityNum, severityLevel, functionName, message);
}
};
const writeLogToDB = async function writeLogToDB(source, severityNum, severityLevel, functionName, message) {
try {
const con = await getConnection();
con.connect(function (err) {
if (err) throw err;
con.query(qryDict.QUERIES.setAddNewLog, [source, severityNum, severityLevel, functionName, message], function (err) {
try {
if (err) {
console.error("addNewLog", err);
}
let response = JSON.stringify({
"result": true,
"message": "success"
});
} catch (err) {
let response = JSON.stringify({
"result": false,
"message": err
});
return response;
} finally {
con.close();
}
});
});
} catch (err) {
con.close();
console.error(err);
}
};
问题出在 writeLogToDB
函数中。
该函数是异步的,但它在内部使用 con.connect
基于回调的机制,没有代码正在等待。
您必须一直使用 promises 才能使 await
-ing 传播:
const writeLogToDB = async function writeLogToDB(
source,
severityNum,
severityLevel,
functionName,
message
) {
const con = await getConnection();
return new Promise((resolve, reject) => {
con.connect(function(err) {
if (err) return reject(err);
con.query(
qryDict.QUERIES.setAddNewLog,
[source, severityNum, severityLevel, functionName, message],
function(err) {
if (err) return reject(err);
resolve(
JSON.stringify({
result: true,
message: "success"
})
);
}
);
});
}).finally(() => {
// note: add a check here to do it only
// if connection is opened to handle edge cases
con.close();
});
};
更简洁的解决方案是将连接方法本身实现为基于承诺,而不是回调。 (也许 util/promisify 可以提供帮助)
那么您将拥有更简洁的代码:
const writeLogToDB = async function writeLogToDB(
source,
severityNum,
severityLevel,
functionName,
message
) {
const con = await getConnection();
try {
await con.connect();
await con.query(qryDict.QUERIES.setAddNewLog, [
source,
severityNum,
severityLevel,
functionName,
message
]);
return JSON.stringify({
result: true,
message: "success"
});
} finally {
// note: add a check here to do it only
// if connection is opened to handle edge cases
con.close();
}
};
如果我的 Node.js v.13.12 应用程序遇到一些技术问题,我想:
- 在数据库中写入日志消息;
- 使用特定代码退出 Node.js 应用程序。
为了实现这种行为,我使用了以下代码:
const onError = async function onError(error) {
await logger.log("Critical error: " + error);
process.exit(UNCAUGHT_FATAL_EXCEPTION);
}
问题是当我执行上面的代码时,我到达await logger.log(…)
,进去然后立即继续process.exit(UNCAUGHT_FATAL_EXCEPTION)
并执行。
因此,应用程序在写入数据库之前关闭,尽管我希望 await
等到 logger.log(…)
完成。
我的问题:
如何确保process.exit(UNCAUGHT_FATAL_EXCEPTION)
只在logger.log(…)
完成后执行而不使用回调?
更新:
整个 logger.log(…)
代码链:
export const log = async function log(source, severityNum, severityLevel, limitSeverityNum, functionName, message) {
if ((severityNum > LOG_LEVELS.OFF.intLevel) && (severityNum <= limitSeverityNum)) {
await writeLogToDB(source, severityNum, severityLevel, functionName, message);
}
};
const writeLogToDB = async function writeLogToDB(source, severityNum, severityLevel, functionName, message) {
try {
const con = await getConnection();
con.connect(function (err) {
if (err) throw err;
con.query(qryDict.QUERIES.setAddNewLog, [source, severityNum, severityLevel, functionName, message], function (err) {
try {
if (err) {
console.error("addNewLog", err);
}
let response = JSON.stringify({
"result": true,
"message": "success"
});
} catch (err) {
let response = JSON.stringify({
"result": false,
"message": err
});
return response;
} finally {
con.close();
}
});
});
} catch (err) {
con.close();
console.error(err);
}
};
问题出在 writeLogToDB
函数中。
该函数是异步的,但它在内部使用 con.connect
基于回调的机制,没有代码正在等待。
您必须一直使用 promises 才能使 await
-ing 传播:
const writeLogToDB = async function writeLogToDB(
source,
severityNum,
severityLevel,
functionName,
message
) {
const con = await getConnection();
return new Promise((resolve, reject) => {
con.connect(function(err) {
if (err) return reject(err);
con.query(
qryDict.QUERIES.setAddNewLog,
[source, severityNum, severityLevel, functionName, message],
function(err) {
if (err) return reject(err);
resolve(
JSON.stringify({
result: true,
message: "success"
})
);
}
);
});
}).finally(() => {
// note: add a check here to do it only
// if connection is opened to handle edge cases
con.close();
});
};
更简洁的解决方案是将连接方法本身实现为基于承诺,而不是回调。 (也许 util/promisify 可以提供帮助)
那么您将拥有更简洁的代码:
const writeLogToDB = async function writeLogToDB(
source,
severityNum,
severityLevel,
functionName,
message
) {
const con = await getConnection();
try {
await con.connect();
await con.query(qryDict.QUERIES.setAddNewLog, [
source,
severityNum,
severityLevel,
functionName,
message
]);
return JSON.stringify({
result: true,
message: "success"
});
} finally {
// note: add a check here to do it only
// if connection is opened to handle edge cases
con.close();
}
};