如何处理错误然后立即脱离承诺链?

2023-12-23

所以我有一个 Express 应用程序,它使用中间件来解析 JSON POST 请求,然后填充req.body目的。然后我有一个承诺链,它使用 Joi 根据模式验证数据,然后将其存储在数据库中。

我想做的是检查这些进程之一后是否抛出错误,通过发送状态代码适当处理它,然后完全中止承诺链。我觉得应该有一些非常干净和简单的方法来做到这一点(也许是某种中断语句?),但我在任何地方都找不到它。这是我的代码。我留下了评论,表明我希望在哪里中止承诺链。

const joi = require("joi");

const createUserSchema = joi.object().keys({
    username: joi.string().alphanum().min(4).max(30).required(),
    password: joi.string().alphanum().min(2).max(30).required(),
});

//Here begins my promise chain 
app.post("/createUser", (req, res) => {
    //validate javascript object against the createUserSchema before storing in database
    createUserSchema.validate(req.body)
        .catch(validationError => {
           res.sendStatus(400);

           //CLEANLY ABORT the promise chain here

           })
        .then(validatedUser => {
            //accepts a hash of inputs and stores it in a database 
            return createUser({
                    username: validatedUser.username,
                    password: validatedUser.password
                })
        .catch(error => {
            res.sendStatus(500);

            //CLEANLY ABORT the promise chain here

        })
        //Only now, if both promises are resolved do I send status 200
        .then(() => {
            res.sendStatus(200); 
            }                 
        )

});

你不能在中间中止承诺链。它将调用.then() or a .catch()在链的后面(假设两者都存在并且假设你的承诺解决或拒绝)。

通常,处理这个问题的方法是放一个.catch()在链的末端,它检查错误类型并采取适当的措施。您没有在链的早期处理错误。你让最后.catch()处理事情。

这是我的建议:

// helper function
function err(status, msg) {
    let obj = new Error(msg);
    obj.status = status;
    return obj;
}

//Here begins my promise chain 
app.post("/createUser", (req, res) => {
    //validate javascript object against the createUserSchema before storing in database
    createUserSchema.validate(req.body).catch(validationError => {
        throw err("validateError", 400)
    }).then(validatedUser => {
            //accepts a hash of inputs and stores it in a database 
            return createUser({
                    username: validatedUser.username,
                    password: validatedUser.password
            }).catch(err => {
                throw err("createUserError", 500);
            });
    }).then(() => {
        // success
        res.sendStatus(200); 
    }).catch(error => {
        console.log(error);
        if (error && error.status) {
            res.sendStatus(error.status);
        } else {
            // no specific error status specified
            res.sendStatus(500);
        }
    });
});

这有几个优点:

  1. 任何错误都会传播到最后.catch()在记录链的末端,并且仅在代码中的一个位置发送适当的状态。
  2. 成功仅在发送该状态的一个位置进行处理。
  3. 这可以无限扩展到链条中的更多环节。如果您有更多可能出现错误的操作,它们可以“中止”链的其余部分(最后一个除外).catch()通过使用适当的错误对象来拒绝)。
  4. 这有点类似于没有太多的设计实践return value语句遍布您的函数,而是累积结果,然后在最后返回它,有些人认为这对于复杂函数来说是一个很好的做法。
  5. 调试时可以在其中设置断点.then()和一个.catch()查看承诺链的最终解决方案,因为整个链经历了最后一个.then()或最后一个.catch().
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何处理错误然后立即脱离承诺链? 的相关文章

随机推荐

  • 如何通过扩展修改 Chrome 中的当前 url 位置

    我想创建一个扩展 如果用户单击扩展按钮 则将用户重定向到另一个网站 到目前为止 我只看到了为每次点击创建一个新选项卡的扩展 是否可以使用活动选项卡将用户重定向到另一个网站 我尝试过这样的事情 chrome browserAction onC
  • 简单的汇编代码会导致段错误吗?

    section data section text globl start start movl 1 eax this is the linux kernel command number system call for exiting a
  • C++0x 中的本地化支持有任何更新吗?

    我对 C 语言环境方面的研究越多 我就越了解 它们已经被破坏了 std time get 不对称std time put 如 C strftime strptime 中所示 并且不允许轻松解析带有 AM PM 标记的时间 I 发现 http
  • 在 C# 中按第一个元素的升序对二维数组行进行排序

    我需要按第一个元素的升序对二维数组行进行排序 如示例所示 5 7 6 2 9 6 4 8 1 gt 2 9 6 4 8 1 5 7 6 我可以在行中找到最大元素 但我现在不知道如何对行进行排序 public double maxInRow
  • PHP:get_used_class() 与 get_class($this)

    在 PHP 中 有什么区别get called class http php net manual en function get called class php and get class this http php net manua
  • SQLite 按小时、天、周、年进行分组/计数

    假设我们有一个简单的 Android 应用程序 只有一个按钮 单击该按钮记录该单击的日期和时间 在 sqlite 中 我想知道记录保存该日期时间的长串或字符串的最佳格式是什么 目的是制作报告来显示 1 选定日期的点击次数总和 按小时分组 2
  • 配置在 Eclipse 中为 Scala 运行

    我是 Scala 的初学者 我在 eclipse 中安装了 Scala IDE 现在我想运行我的应用程序 它从不显示 作为 Scala 应用程序运行 而是显示 作为 Java 应用程序运行 或 Java 小程序 我打开 运行配置 并单击 S
  • 使用 SSL/Keystore 连接到 Java 中的 Websphere MQ

    我想通过 Java 连接到 Websphere 6 0 MQ 我已经有了 普通 队列的工作代码 但现在我需要访问一个经过 SSL 加密 密钥库 的新队列 我收到了一个名为 Something jks 的文件 我认为它是我需要存储在某处的证书
  • html5中的
    标签可以用作背景图片吗?

    我开始阅读 html5 并且正在尝试开展一个项目 以便我可以了解事情是如何工作的 我知道标签可以这样使用
  • zsh:找不到命令:express

    我安装了node和npm并且都工作正常 但是 当我尝试通过安装 Express 时npm install g express I get zsh 找不到命令 express 我尝试在我的中添加各种路径 zshrc文件没有运气 如果我回声 p
  • 更改使用 catplot 或 barplot 创建的条形图的宽度

    我正在尝试使用seaborn factorplot 创建条形图 我的代码如下所示 import seaborn as sns import matplotlib pyplot as plt df pd read csv data csv f
  • 如何在 Dotrine 2 中配置命名策略

    我读了chapter http docs doctrine project org projects doctrine orm en latest reference namingstrategy html关于手册中的 Doctrine 命
  • Tkinter - 等重的列不等宽

    我有一个包含三列的 Tkinter 顶级窗口 所有三列均配置为具有相同的权重 内柱0 and 2是子框架 里面有Listbox小部件 内柱1是一组按钮 由于某种原因 尽管我的 3 列具有相同的权重 但这些列表框 强制 它们的列占用更多空间
  • mypy:“__eq__”与超类型“object”不兼容

    这是我的代码 class Person def init self id self id id def eq self other Person gt bool return self id other id def compare sel
  • 转换忽略 sf::Sprite 的起源

    在 SFML 中变换精灵 不考虑它的新原点 在我的例子中 sf Sprite 围绕左上角 0 0 的轴旋转 无论其原点如何 之前使用 setOrigin 设置新的原点无效 我确信精灵会更早地获得正确的原点位置 即矩形的中心 My code
  • UIGestureRecognizers 的多个手势(iPhone、Cocos2d)

    我使用 Cocos2d 渲染精灵 并使用 UIGestureRecognizers 允许用户平移 旋转和缩放精灵 我使用如下代码单独工作 UIPinchGestureRecognizer pinchRecognizer UIPinchGes
  • 如何在android中对这行LayoutInflater.from()进行单元测试

    您好 我正在构建一个简单的 RecyclerView 适配器 并尝试测试适配器的所有方法 但 onCreateViewHolder 对我来说很困难 Override public NewsViewHolder onCreateViewHol
  • 具有 ViewModel 和行为的 Xamarin 视图

    我有一个视图 其中包含当前用户的用户配置文件 该视图包含一个视图模型 该模型具有与用户名或电子邮件地址等单个属性的双向绑定 该视图还有一个行为 它会验证输入并显示输入无效的错误 由于双向绑定 即使行为表明输入错误 视图模型也会更新值 我需要
  • 如何在 R 上使用 dodged geom_boxplot 为每个方面注释不同的值?

    我正在尝试使用组 填充 和构面向我的 ggplot 箱线图添加重要性星号 Using geom signif 我可以添加栏 例如 我也试图对躲避的箱线图做同样的事情 类似于 想象一下较小的线上方有显着性值 前一张图的代码 data libr
  • 如何处理错误然后立即脱离承诺链?

    所以我有一个 Express 应用程序 它使用中间件来解析 JSON POST 请求 然后填充req body目的 然后我有一个承诺链 它使用 Joi 根据模式验证数据 然后将其存储在数据库中 我想做的是检查这些进程之一后是否抛出错误 通过