[英]Async/await in Nodejs + Mongoose
我是 Promises 和 async/await 编程的新手,我不确定我是否理解正确。 我正在 Nodejs 中创建一个 API,使用 Express、ZCCADCDEDB567ABAE643E15DCF0974E503Z 和 MongoDB。 我看过很多关于如何处理异步性的教程,但它们都是关于路由和数据库查询在同一个文件中的 NodeJs 项目。 例子:
const asyncMiddleware = fn =>
(req, res, next) => {
Promise.resolve(fn(req, res, next))
.catch(next);
};
router.get('/users/:id', asyncMiddleware(async (req, res, next) => {
const something = await getSomethingFromDb({ id: req.params.id })
res.json(something);
}));
但是,为了清楚起见,我已将路由与 controller 分开,但我非常怀疑我是否正确地完成了它。 这是我的代码:
路由器.js
const asyncMiddleware = fn =>
(req, res, next) => {
Promise.resolve(fn(req, res, next))
.catch(next);
};
router.get('/something/:id', asyncMiddleware(async (req, res, next) => {
const answer = await somethingController.findById(req, res, next)
}));
controller.js
exports.findById = async (req, res, next) => {
const something = await Something.findById(req.params.id).exec();
res.send(something);
};
我尝试使用 console.log() 来检查打印的内容,但我已经意识到,由于等待部分,整段代码将等待查询完成。 这实施得好吗? 我该如何测试它?
版本:NodeJs v10.16.3 ZCCADCDEDB567ABAE643E15DCF0974E503Z v5.7.1
首先,您不需要“asyncMiddleware”。 让我举一个完整的例子来说明如何分离路由和控制器,同时保持 controller 异步:
Controller
exports.findById = async (req, res, next) => {
try{
const something = await Something.findById(req.params.id).exec();
res.send(something);
}catch(err){
return res.status(500).send({
message: err.message
})
}
};
您应该将async
调用包装在 try/catch 块中。
路线
然后,您只需在您的路线中调用您的 controller ,如下所示:
router.get('/:id', Controller.findByID)
就是这样。 您的路由不需要任何额外的async
调用。
如果你有中间件你想添加你的路由,你可以这样做:
//for single middleware
router.get('/:id',somethingMiddle,Controller.findByID)
//for multiple middleware
router.get('/:id',[somethingMiddle, anotherMiddle],Controller.findByID)
让我知道这是否有帮助
就个人而言,我会坚持将 try-catch 用于我的异步功能,而不是使用中间件。 这可能类似于以下内容:
module.exports.view = async function(req, res, next) {
try {
var something = await Something.findById(req.params.id).orFail();
res.send(something);
} catch (err) {
next(err);
}
};
然后在您的路由器中,它只是:
router.get('/something/:id', somethingController.view);
这样做将允许您在next(err)
将其发送到全局错误处理程序之前操纵和处理 controller 操作的特殊错误情况。
现在我不确定这是否是您所期望的,但您可能想在查询中调用.orFail()
。 这样,如果找不到具有指定 ID 的“某物”,则会引发错误。 否则, something
变量将为 null。 但这完全取决于您希望 API 到 function 的方式。
此外,当您定义async
function 时,基本上是说 function 返回Promise
。 await
语句基本上告诉程序暂停 function 直到 promise 得到解决。 在此示例中, await
将等待数据库返回结果,然后再继续执行 controller 操作。 Express 将神奇地处理等待您的async
路由方法和中间件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.