Express Router.post未等待中间件next()就提前执行问题排查
问题根源
问题来自中间件异步逻辑处理错误,和Express Router执行机制无关:
- 同步写法的
try/catch无法捕获.then()回调内的Promise异步异常,一旦post.save()执行失败,会出现未捕获的Promise报错,同时导致请求流程失控 - 代码没有等待
post.save()异步数据库操作执行完成,中间件同步段执行结束后没有锁定流程顺序,会出现路由处理逻辑在req.success赋值前就被触发的情况。
修复代码
将中间件改为async/await写法,让所有异步操作被try/catch正确捕获,严格保证执行顺序:
module.exports = async (req, res, next) => { try { if (req.authorization && req.authorization.access_level < 3) { const post = new postsModel(req.body); const savedPost = await post.save(); console.log(savedPost); req.success = true; next(); } else { throw new Error('unauthorized access'); } } catch (err) { res.status(400).send({ error: true, message: err.message }); } };
编写规范
- Express 4.x 不会自动感知普通函数返回的Promise,必须手动通过
await等待异步操作执行完成后,再决定是返回响应还是调用next() - 不要在中间件里混用
.then()回调和next()控制流程,很容易出现重复调用next()、异常漏捕获、流程提前触发的问题 - 涉及数据库、网络IO的异步中间件,统一使用
async/await语法可以规避绝大多数流程顺序问题。
内容的提问来源于stack exchange,提问作者Paweł Czekaj
相关产品推荐
相关产品推荐

