【发布时间】:2025-12-16 03:00:01
【问题描述】:
在快速路由中,我想记录用户对数据库的访问,但不包含:
- 在执行用户想要的任务之前等待它完成
- 关心记录是否成功
我想知道代码是否正确。
此线程 (Down-side on calling async function without await) 基本上发布了相同的问题,但响应是避免使函数异步。然而,由于sequelize 的upsert 返回了一个承诺,我不确定我是否在下面的代码中正确地做到了这一点。有人可以验证吗?
我还注意到,如果您不在异步函数的 try-catch 块中等待一个 Promise,则任何在 Promise 中抛出的错误都将无法处理。因此,我确保logAccess 捕获并处理任何错误。这是正确的做事方式吗?
const { Router } = require('express');
const moment = require('moment-timezone');
const Sequelize = require('sequelize');
function timeout(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
const userTable = sequelize.define('user', {
user_id: {
type: Sequelize.UUID,
primaryKey: true,
},
last_login: {
type: 'TIMESTAMP',
},
});
const logAccess = (user) => userTable.upsert({
user_id: user.user_id,
last_login: moment().tz('Australia/Sydney').format('YYYY-MM-DD HH:mm:ss'),
}).catch(() => console.log('Logging access to db failed'));
const makeCandy = async (user) => {
await timeout(1000);
return 'chocolate';
}
router.get('/get_candy', async (req, res) => {
try {
const user = req.body.user;
// Log access without blocking thread
logAccess(user);
const candy = await makeCandy(user)
res.status(200).send({ candy })
} catch (e) {
console.log(e);
}
})
【问题讨论】:
-
是的,就是这样。不过,我将
resolve('chocolate');视为错字。 -
我投票结束这个问题,因为它最适合codereview.stackexchange.com。
-
await不会阻塞线程。它的工作方式类似于yield,因为它暂停函数并稍后恢复执行。 -
另外,
await是 Promise 的语法糖——你只能等待那些,所以你可以重写任何await代码来处理 Promise。await有时在代码布局方面是更好的选择,它的功能并没有根本不同。 -
您发现的另一个问题不符合您的要求,因为您需要错误处理。拥有一个不返回承诺的异步函数从来都不是一个好主意——正如他们所写的那样,它是
weirdFunction。是的,像你一样使用.catch()是可以的,尽管我宁愿把它放在调用logAccess(user)的路由处理程序中——只是为了明确表示不等待它。
标签: javascript node.js asynchronous async-await