【问题标题】:How could I generalize a http response handler in Node.js?如何在 Node.js 中概括一个 http 响应处理程序?
【发布时间】:2018-02-03 18:32:23
【问题描述】:

我正在为节点应用程序编写一个 rest api,我发现自己重写了很多类似以下的内容:

function(req, res, next) {
  databaseCall()
  .then( (results) => {
    if (results != null) {
      res.status(200).send(results);
    } else {
      res.sendStatus(404);
    }
  })
  .catch(function(err) {
    console.log("Request error: " + err.stack);
    res.sendStatus(500);
  })
}

我想重构响应部分,所以我可以做类似的事情

databaseCall()
.then(handleResponse)

handleResponse 将负责整个响应/捕获过程。 但我无法完全弄清楚如何做到这一点。 databaseCall 方法因端点而异——有时它需要一个参数,有时不需要。我可以创建一个通用函数表达式来获取 databaseCall 结果并将其粘贴到承诺链中,但我不知道如何访问该函数内的响应对象。我知道我可以添加另一个函数来组合所有内容,如下所示:

function(databaseCall, parameter, req, res, next) {
  databaseCall(parameter)
  .then( (results) => {
    if (results != null) {
      res.status(200).send(results);
    } else {
      res.sendStatus(404);
    }
  })
  .catch( (err) => {
    console.log("Request error: " + err.stack);
    res.sendStatus(500);
  })
}

但这看起来很难看,因为 databaseCall 可能有 0 个参数。我认为有一个更优雅的解决方案。

【问题讨论】:

  • 你不能只创建一个新函数来做你想做的事情并在你需要的任何地方调用它吗?决定传递哪些参数是有意义的,这样您就可以拥有最通用的实现。
  • 喜欢我列出的最后一个函数吗?我知道我可以做这样的事情,我想这似乎是一个草率的解决方案。也许我只是挑剔。
  • 为了让我们就重构的最佳方式提出建议,我们必须查看您尝试在重构中合并的所有内容的代表性样本,以便我们知道总体目标是什么。由于您实际上只显示了一个代码 sn-p,因此我不知道所有重构真正需要完成什么。但是,是的,您展示的一个功能是实现它的一种方法。
  • 仅供参考,传递任意参数的更通用方法是传递一个对象,让调用者为该对象分配适合给定情况的任何属性。然后,您的包装函数只需将对象传递给底层数据库调用。

标签: javascript node.js rest express promise


【解决方案1】:

您的想法可能是正确的,您只需要更进一步,将 db 调用保持在通用处理程序之外,并将其作为 Promise 传递

// generic handler for db promise
// the promise is created outside and passed as arg
function responseFromDb(databaseCallPromise, res) {
  databaseCallPromise
  .then((results) => {
    if (results != null) {
      res.status(200).send(results);
    } else {
      res.sendStatus(404);
    }
  })
  .catch((err) => {
    console.log(`Request error: ${err.stack}`);
    res.sendStatus(500);
  });
}

// handler per request, only needs to create db call with the desired params
// and pass it to the generic handler, which will take care of sending the response
function(req, res, next) {
  responseFromDb(databaseCall(param1, param2), res)
}

【讨论】:

  • 这正是我所希望的。我无法理解将调用本身作为参数传递等同于传递承诺这一事实。解决了参数变化的问题。谢谢。
  • @cweber105 不客气。如果此解决方案适用于您的问题,请接受答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-22
  • 2019-08-27
  • 2019-03-28
  • 1970-01-01
  • 1970-01-01
  • 2016-09-20
  • 1970-01-01
相关资源
最近更新 更多