Express JS 在请求上使用异步函数
Posted
技术标签:
【中文标题】Express JS 在请求上使用异步函数【英文标题】:Express JS use async function on requests 【发布时间】:2019-01-03 06:00:28 【问题描述】:app.use(async function(req, res, next)
try
var myres = await new Promise((resolve, reject) =>
mysql_connection.query("select * from Users;", (err, rows) =>
if (err)
reject(err);
else
resolve(rows);
);
);
catch (error)
console.log(error);
);
问题是。使用 async 函数可以将 await 用于 DB 查询可以吗?恐怕这会在expressjs方面引起一些问题。
【问题讨论】:
你是否故意忽略myres
?否则,您可以简单地调用 next
并显示错误(如果有)(我假设您已经知道这一点)。
【参考方案1】:
async..await
是 promise 的语法糖,promise 只是一种依赖回调的模式。只要环境支持async
函数,就可以使用它们。从 Node.js 7.6.0 开始支持 async..await
。
async
函数总是返回一个承诺。只要这个隐式返回值不会引起问题,它在任何地方都很好,包括 Express。不管是用于数据库查询还是其他用途。
除非 API 支持 Promise,否则错误应该完全在 async
函数中处理。函数体应该用try..catch
包裹起来,以排除未处理的拒绝,这可能会导致未来的 Node 版本出现异常。
原始代码不包含next
调用,只是抑制了一个错误。根据经验,async
中间件的结构应该是这样的:
app.use(async function(req, res, next)
try
...
next();
catch (error)
next(error);
);
【讨论】:
estus 为什么catch里面的代码包含next?正如你提到的The original code contains no next calls and just suppresses an error.
注意:如果我不使用下一个,它仍然会抛出 unhandle Promise 警告。另外,我遇到了这个问题:***.com/questions/13133071/…
另外,如果您也可以在这个问题上花一两分钟时间? ***.com/questions/53941672/…(会很有帮助)
抑制错误很少是个好主意。对于应该发送响应的中间件(这在 OP 中未显示),什么都不做将导致无响应和请求超时。 next
将错误委托给 Express 错误处理程序。这是在 Express 中处理错误的常用方法。您可以使用res.status(400).send(...)
而不是next(err)
,以防您有更具体的想法如何处理此错误。 如果我不使用 next,它仍然会抛出 unhandle Promise 警告。 - 你可能做错了什么。【参考方案2】:
异步等待可以毫无问题地用于数据库查询。你可以使用 try catch 但是有一个更优雅的解决方案,它允许你使用 express 提供的错误处理中间件:
你用这个函数包装你的中间件:
const asyncMiddleware = fn =>
(req, res, next) =>
Promise.resolve(fn(req, res, next))
.catch(next);
;
那么你可以通过以下方式使用它:
const asyncMiddleware = require('./utils/asyncMiddleware');
router.get('/', asyncMiddleware(async (req, res, next) =>
/*
if there is an error thrown in getUserFromDb, asyncMiddleware
will pass it to next() and express will handle the error;
*/
const user = await getUserFromDb( id: req.params.id )
res.json(user);
));
如果抛出错误,控制权将移交给错误处理中间件,该中间件是具有如下四个参数的中间件:
app.use(function (err, req, res, next)
// your error code
)
【讨论】:
嗨,谢谢你的回答,你能解释一下包装器是如何工作的吗:) 我不是 javascript 专业人士,所以阅读该代码有点令人困惑 漂亮,就是太优雅了【参考方案3】:您还可以在您的 server.ts 或 server.js 上导入 https://www.npmjs.com/package/express-async-errors 来处理 express 上的异步错误
yarn add express-async-errors
然后在你的主文件中导入import 'express-async-errors';
。
【讨论】:
【参考方案4】:使用异步函数来等待数据库查询是完全可以的。但是尝试将该代码嵌入到 try 和 catch 块中,以便捕获异常。
【讨论】:
但是没有任何事情没有得到答复,它不会在快递方面引起一些不可预测的行为吗? 不会的。请看看这个博客:medium.com/@Abazhenov/…我希望它有所帮助。以上是关于Express JS 在请求上使用异步函数的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Express 请求处理程序中编写非阻塞异步函数 [重复]
如何在 Express 请求处理程序中编写非阻塞异步函数 [重复]
从 node.js/express.js 中的多个异步源构建对象