我很好奇这里的最佳实践。
据我所知,Node(单个进程)的本质是,我了解对Web请求的响应不会结束该进程。因此,假设返回值无关紧要(UPDATE),为什么我们需要等待诺言完成才能返回给客户?
换句话说,这是一条简单的Express路线:
router.post('/:perId/settings', auth.check, async (req, res) => {
try {
let per_id = req.params.perId;
let per_first_name = req.body.per_first_name.trim();
let per_last_name = req.body.per_last_name.trim();
let per_ea_address = req.body.per_ea_address.trim();
let per_tel_number = std.num_only(req.body.per_tel_number);
let promises = [];
let responses;
promises.push(db.f.stmt((`UPDATE PER SET PER_DATE_UPDATED = CURRENT_TIMESTAMP, PER_FIRST_NAME = @PER_FIRST_NAME, PER_LAST_NAME = @PER_LAST_NAME WHERE PER_ID = @PER_ID`), [
{var: 'PER_ID', type: sql.Int, val: per_id},
{var: 'PER_FIRST_NAME', type: sql.VarChar(25), val: per_first_name},
{var: 'PER_LAST_NAME', type: sql.VarChar(25), val: per_last_name}]));
promises.push(db.f.stmt((`UPDATE EA SET EA_DATE_UPDATED = CURRENT_TIMESTAMP, EA_ADDRESS = @EA_ADDRESS WHERE PER_ID = @PER_ID`), [
{var: 'PER_ID', type: sql.Int, val: per_id},
{var: 'EA_ADDRESS', type: sql.VarChar(60), val: per_ea_address}]));
promises.push(db.f.stmt((`UPDATE TEL SET TEL_DATE_UPDATED = CURRENT_TIMESTAMP, TEL_NUMBER = @TEL_NUMBER WHERE PER_ID = @PER_ID`), [
{var: 'PER_ID', type: sql.Int, val: per_id},
{var: 'TEL_NUMBER', type: sql.VarChar(10), val: per_tel_number}]));
promises.push(per.insert_history(per_id, (`Settings updated.`), req.user.PER_ID));
responses = await Promise.all(promises); promises = []; // is this necessary?
res.status(200).send(column_value);
} catch (err) {
await std.log('Unknown error caught', req.originalUrl, err);
res.status(500).send(('Unknown error caught in ' + req.originalUrl));
}
});
是否需要添加以下行:
responses = await Promise.all(promises);
该过程不会退出,因此诺言将继续履行,对吗?根据我的测试经验,正如预期的那样,它们确实会在响应Web请求后继续运行。但是,我觉得自己在作弊。
很显然,我只是想尽快返回Web请求。
顺便说一句,如果发生故障,我的db.f.stmt()函数将使失败的语句排队,并在几秒钟后自动重试它们。如果它们仍然失败,则会通过电子邮件发送给我,以便我修复并手动运行。
这很重要,因为上面的查询只会导致系统问题而不是用户错误,因此失败。因此,返回错误可能不是最好的选择。