【问题标题】:UnhandledPromiseRejectionWarning despite multiple Error checksUnhandledPromiseRejectionWarning 尽管有多次错误检查
【发布时间】:2020-01-09 03:42:49
【问题描述】:

我最近一直在用 NODEJS 开发一个网络应用程序。我有一个负责所有 crud 操作的数据库模型。示例数据库模型

    getDeviceList: function () {
        return new Promise(function (resolve, reject) {
            var sql = "SELECT * FROM `devices`";
            db.query(sql, function (err, result) {
                if (err) {
                    console.log(`FAILED: ${err}`);
                    reject(err);
                } else resolve(result);
            });
        });
    }

我在 DB 模块中访问此功能,如

router.get("/inventory/devices", checkAuth, function (req, res, next) {
    return new Promise(function (resolve, reject) {
        db.getDeviceList().then(function (result) {
            resolve(res.status(200).json(result));
        }).catch(function (err) {
            console.log(`FAILED: ${err}`);
            reject(res.status(200).json(err));
        });
    });
});

有时当我关闭数据库时;我得到 UnhandledPromiseRejectionWarning 但在我看来,我正在处理所有的承诺。处理承诺的最佳方式是什么?我的 rerun promise 方法是否正确? 我的数据库连接块在app.js

var connection = db.connectDB().then(function (connect) {}).catch(function (err) {
    console.log(`FAILED: ${err}`);
});

而我的connectDB()

function () {
        return new Promise(function (resolve, reject) {
            db = mysql.createPool({
                host: "localhost",
                port: 3306,
                user: "migration",
                password: "iub5015",
                database: "migration"
            });
            db.getConnection(function (err) {
                if (err) {
                    console.log(`FAILED: ${err}`);
                    reject(err);
                } else {
                    console.log("Connected");
                    resolve(db);
                }
            });
        });
    }

【问题讨论】:

    标签: javascript node.js promise node-mysql request-promise


    【解决方案1】:

    你的 catch 块中的最后一条语句,

    reject(res.status(200).json(err));
    

    表示返回的 Promise 处于拒绝状态。即router.get("/inventory/devices", checkAuth, function (req, res, next) 返回的 Promise 处于拒绝状态,您错过了这一点。 (或者 express 没有像你的情况那样捕捉到)

    这就是您收到此 UnhandledPromiseRejectionWarning 的原因。

    处理承诺的最佳方式是什么,是我重新运行的方法 承诺正确吗?

    嗯,根据我的经验,这取决于。在某些情况下,您可能希望通过拒绝 Promise 来传播错误,或者在某些情况下,您可能只想以某种方式处理它并将某些内容作为解析值返回。在您的情况下,您可能需要查看 express 文档以弄清楚您需要如何在中间件中实现承诺。

    router.get("/inventory/devices", checkAuth, function (req, res, next) {
        return new Promise(function (resolve, reject) {
            db.getDeviceList().then(function (result) {
                resolve(res.status(200).json(result));
            }).catch(function (err) {
                console.log(`FAILED: ${err}`);
                // This will not give UnhandledPromiseRejectionWarning 
                resolve(res.status(500).json(err));
            });
        });
    });
    

    【讨论】:

    • 但如果在这两种情况下我都解决了这个问题;我的前端的 try catch 实际上不起作用。对吗?
    • 你不应该混合前端后端的东西,把它们当作两个不同的实体
    • 对于前端,我猜resolve(res.status(500).json(err))仍然会被视为错误,因为响应的http错误代码将是500。
    • 所以,在你的设计中,我将依赖于状态码。无论如何,我都发送了 200 个。
    • 它基本上是管理这些规则的 HTTP 协议。 res.status(2xx) 将发送 2xx 的 http 状态码,即成功,res.send(4xx)res.send(5xx) 将发送 4xx 和 5xx 系列的状态码,将被视为错误。请查看这些 MDN 文档
    【解决方案2】:
        router.get("/inventory/devices", checkAuth, function (req, res, next) {
        new Promise(function (resolve, reject) {
            db.getDeviceList().then(function (result) {
                resolve(result);
            }).catch(function (err) {
                console.log(`FAILED: ${err}`);
                reject(err);
            });
        }).then(r => {
            res.status(200).json(r)
         }).catch(er => {
           res.status(400).json(er)
         })
    });
    

    【讨论】:

    • 第二个捕获的是什么?新的承诺?
    • 如果可能,请添加一些上下文。
    • 在路由器中,你没有处理这个promise。
    • 应该如何处理?如果我使用 db 模型; db 模型应该返回新的承诺吗?如果我使用路由器;路由器应该返回新的承诺吗?
    • 是的。在需要的地方使用 Promise。在你的路由器中,我认为这里需要承诺。
    猜你喜欢
    • 1970-01-01
    • 2019-07-09
    • 1970-01-01
    • 2019-10-15
    • 1970-01-01
    • 1970-01-01
    • 2018-02-23
    • 2021-11-17
    • 1970-01-01
    相关资源
    最近更新 更多