让 Express 中间件支持 Promise

发布于 2022-07-29 00:31:00 字数 3171 浏览 189 评论 0

Express 的中间件或者路由不支持 promises 或者 async/await,在下面的例子中,Express 永远不会发送响应,应为有一个未处理的异常 unhandled promise rejection

const app = require('express')();

app.get(async function routeHandler(req, res) {
  // Will throw an error because `req.params.bar` is undefined
  req.params.bar.toString();

  // Request will hang forever because `res.json()` never gets called.
  res.json({ test: 42 });
});

const server = await app.listen(3000);

// Will time out. If not for the `timeout` option, would hang forever.
const err = await axios.get('http://localhost:3000', { timeout: 300 }).
  catch(err => err);
err.message; // "timeout of 300ms exceeded"

为了确保您的 Express 应用程序不会永远挂起,您需要确保您的中间件函数调用 next() 并且您的路线处理程序调用 res.send() 或者 res.json(),最简单的方法是使用 @awaitjs/express

const app = require('express')();
const { addAsync } = require('@awaitjs/express');
addAsync(app);

// @awaitjs/express adds a `getAsync()` function to Express
app.getAsync(async function routeHandler(req, res) {
  // The `getAsync()` function knows to look out for promise rejections
  req.params.bar.toString();

  res.json({ test: 42 });
});

const server = await app.listen(3000);

const err = await axios.get('http://localhost:3000').
  catch(err => err);
err.message; // "Request failed with status code 500"

如果您不想使用外部库,您可以自己处理错误。 使用 async/await,您可以将逻辑包装在 try/catch 以确保错误被​​捕获。 只要确保你的 catch 块不会引发错误。

const app = require('express')();

app.get(async function routeHandler(req, res) {
  // Wrap your route handler logic in a try/catch, and make sure
  // to respond if an unexpected error occurs.
  try {
    req.params.bar.toString();

    res.json({ test: 42 });
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
});

const server = await app.listen(3000);

const err = await axios.get('http://localhost:3000').
  catch(err => err);
err.message; // "Request failed with status code 500"

如果您使用的是承诺链,您应该 使用 Promise#catch() 功能

const app = require('express')();

app.get('/', function routeHandler(req, res) {
  return Promise.resolve().
    then(() => req.params.bar.toString()).
    then(() => res.json({ test: 42 })).
    // Make sure you call `.catch()` on your promise to handle errors!
    catch(err => res.status(500).json({ message: err.message }));
});

const server = await app.listen(3000);

const err = await axios.get('http://localhost:3000').
  catch(err => err);
err.message; // "Request failed with status code 500"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

友欢

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

linfzu01

文章 0 评论 0

可遇━不可求

文章 0 评论 0

枕梦

文章 0 评论 0

qq_3LFa8Q

文章 0 评论 0

JP

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文