【问题标题】:How do I rewrite a series of conditional statements with Q promises in node.js?如何在 node.js 中用 Q Promise 重写一系列条件语句?
【发布时间】:2014-02-21 02:33:24
【问题描述】:
exports.create = function(req, res) {
  var company_id = req.company_id;
  var client = new Client(req.body);

  Company.findOne({_id: company_id}, function(err, company) {
    if(err) {
      response = {
        status: 'error',
        error: err
      }

      return res.json(response);
    } else if(!company) {
      response = {
        status: 'error',
        error: 'Invalid company_id'
      }

      return res.json(response);
    } else {
      client.save(function(err) {
        if(err) {
          response = {
            status: 'error',
            error: err
          }
        } else {
          response = {
            status: 'ok',
            client: client
          }
        }

        return res.json(response);
      });
    }
  });
}

这是我的代码(如果重要,请使用 Express)。我正在尝试了解有关承诺的更多信息,特别是Q。我觉得这是一种完美的逻辑,可以通过承诺来避免这种毛茸茸的条件嵌套。但我不知道如何开始?

【问题讨论】:

    标签: node.js promise q


    【解决方案1】:

    但我不知道如何开始?

    首先删除回调并改用 Promise 方法。然后将错误处理放在专用的错误回调中,而不是使用该条件。此外,您可以将构建 response 对象的代码放在最后(删除重复项),然后只将 err 传递/扔给它。

    exports.create = function(req, res) {
      var client = new Client(req.body);
    
      Q.ninvoke(Company, "findOne", {_id: req.company_id}).then(function(company) {
        if(!company)
          throw 'Invalid company_id';
        else
          return company;
      }).then(function(company) {
        return Q.ninvoke(client, "save");
      }).then(function(saveResult) {
        return {
          status: 'ok',
          client: client
        };
      }, function(err) {
        return {
          status: 'error',
          error: err
        };
      }).done(function(response) {
        res.json(response);
      });
    };
    

    【讨论】:

      【解决方案2】:

      这并不是 Promises 的真正用例。 Promise 是一种消除 node.js 中深度嵌套回调的方法,而不是处理结果的复杂逻辑,就像您在代码中所做的那样。想想.findOne 查询的结果将决定您需要进行的下一个查询的情况——这很快会导致嵌套回调情况,可以减少嵌套,更自然地阅读、评估、重构,如果您使用 Promises,则可以在此基础上进行构建。

      对于.save 调用的结果,您确实有一个嵌套回调。因此,您可以使用 Promises 成功地重构它,就像这样

      new Promise(function() {
          Company.findOne()
          ...
      .then(function(company) {
          company.update()
          ...
      }, function(err) {
          ...
      })
      

      起点是包装您的第一个查询,以便它返回一个承诺,而不是在回调中处理回调。

      【讨论】:

      • 清除深层嵌套回调根本不是 Promise 的用例,您甚至可以使用异步库或简单地命名函数来避免嵌套。
      • 确实有其他方法和库可以帮助解决我认为原始问题所问的问题。但是,更简单地组合一系列串行(或并行)操作是 Promise 的既定动机之一。
      猜你喜欢
      • 2019-05-28
      • 1970-01-01
      • 2014-05-05
      • 1970-01-01
      • 2011-03-21
      • 1970-01-01
      • 2014-11-07
      • 2018-12-17
      • 1970-01-01
      相关资源
      最近更新 更多