【问题标题】:Exit series of nested call backs退出系列嵌套回调
【发布时间】:2015-10-19 19:16:58
【问题描述】:

在下面的代码中,当从deleteUser 的回调函数返回err 变量时,我想将错误插入数据库并以return res.send(500) 结束HTTP 请求(以及整个代码块)。

即使 HTTP 请求已经结束,代码也会继续运行并调用 db.destroy。帖子底部的日志证明了这一点。

// DELETE
app.del('/api/users', function(req, res) {
    var id = req.query.id;

    // get latest copy of database entry first, in case we need to save error message
    db.get(id, {revs_info: true}, function(err, doc) {
        if (err) {
            console.error('Unable to find document', id, 'due to:', err);
            return res.send(500);
        } else {
            // issue delete request first, if fails save error message
            deleteUser(doc.EmailAddress, function(err) {
                if (err) {
                    // update database with error message (if there's already a message, append)
                    doc.Notes = (doc.Notes === '') ? err : err + " " + doc.Notes;

                    db.insert(doc, function(err, document) {
                        if(err) {
                            console.error('Deleting a user failed (1) and updating database with error status failed (2) as well. 1:', doc.Notes, '2:', err);
                            return res.send(500);
                        } else {
                            console.error('Deleting a user failed (with the following) and the error has been stored in the database:', doc.Notes);
                            return res.send(500);
                        }
                    });
                }

                // proceed to delete from database as well
                db.destroy(doc._id, doc._rev, function (err, body) {
                    if(err) {
                        console.error('Error deleting document', doc._id, 'with:', err);
                        return res.send(500);
                    } else {
                        if (doc._revs_info) delete doc._revs_info;
                        console.log('Succesfully deleted user from system and our database:', doc);
                        return res.send(200);
                    }
                });
            });
        }
    });
});

我认为这是因为我的 return 语句只结束了 db.insert 函数。

在node中有解决这个问题的通用设计模式吗?

我是否应该在 db.insert 声明之后但在结束 if (err) { 代码块之前添加另一个 return 语句?

向我的服务器实例发出 DELETE 请求后的日志:

Deleting a user failed (with the following) and the error has been stored in the database: POST 500 has returned an error.

127.0.0.1 - - [Mon, 19 Oct 2015 02:50:19 GMT] "DELETE /api/users?id=11 HTTP/1.1" 500 21 "http://localhost:3000/" "Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0"

Succesfully deleted user from system and our database: { _id: '11',
  _rev: '3-e6fec584448d664476ddaf3b7e150cd7',
  EmailAddress: 'testuser@xyz.com',
  Status: 0,
  Notes: 'POST 500 has returned an error.' }

【问题讨论】:

    标签: javascript node.js express callback


    【解决方案1】:

    首先,是的,在关闭if() {} 之前添加return 语句。这很关键。

    其次,您的代码受到callback hell 的影响,您应该认真考虑切换到更“现代”的替代方案,我个人最喜欢的是承诺。 Here's a great article about this.

    对于节点,请尝试查看 bluebird 或 es6-promisify

    【讨论】:

      【解决方案2】:

      你可以在某个高处引入一个默认为 false 的错误标志:

      var bFatalError = false;
      

      在您检测到致命错误的任何地方,在返回之前设置此标志:

      bFatalError = true;
      

      如果设置了标志,您可以在每个代码块的顶部进行测试和中止:

      if (bFatalError) { return; } 
      

      通过这种方式,您是在向其他代码发出信号,使其不要启动。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-08-24
        • 1970-01-01
        • 2015-12-08
        • 2013-09-11
        • 1970-01-01
        • 1970-01-01
        • 2013-07-13
        • 2020-01-14
        相关资源
        最近更新 更多