快递和猫鼬 - 不能打电话给方法'得到'未定义 - 使用res.json()

时间:2014-09-28 19:45:55

标签: node.js express callback mongoose bind

感谢你的到来。

问题: 我制作了一个小猫鼬"中间件"处理猫鼬错误:

// callback function called at each mongoDB response
var handleDbRes = function(callback) {
    return function (err, entries) {
        if (err) {
            err.status = 500;
            return next(err);
        }

        return callback(entries)  // that line throw the exception
    }
};

所以我将它用于api端点,例如:

someRouter.get('/', function(req, res) {
    models.article.find(handleDbRes(res.json))
})

使用该代码,我遇到错误:

  

TypeError:无法调用方法' get'未定义的

我跟着异常并查看了res.json()声明,在调试时,我想通了:

var app = this.app;
var *** = app.get('***') // that line throw the exception

我猜这个应用程序没有定义因为应用程序不存在于"这个"。

请你能帮我解决这个问题吗?我认为原因很简单,但我不明白......

感谢您的聆听;)

编辑:我尝试了res.json.bind(res)并且它按照我的想法运行了,但是对于大多数api端点来说这种绑定方式真的太糟糕了,我想还有另一个没有它的方法来做这种功能。

编辑:感谢Mscdex的建议,我这样修改了我的代码:

.get('/', function(req, res, next) {
            models.article.find(handleDbRes(res.json.bind(res), next))

...
...
// callback function called at each mongoDB response
var handleDbRes = function(successCallback, errorCallback) {
    return function (err, entries) {
        if (err) {
            err.status = 500;
            return errorCallback(err);
        }

        return successCallback(entries)
    }
};

1 个答案:

答案 0 :(得分:0)

当您传递res.json时,json()函数的上下文将丢失(它不再知道this是什么,因为它没有绑定)。所以这里有一些可能的解决方案:

使用该函数的绑定版本,以便this内的json()始终能够正确评估:

someRouter.get('/', function(req, res) {
  models.article.find(handleDbRes(res.json.bind(res)))
})

或者改为使用包装函数:

someRouter.get('/', function(req, res) {
  function respondJSON(val) {
    res.json(val);
  }
  models.article.find(handleDbRes(respondJSON))
})

或者只是传递res并在res.json()内拨打handleDbRes()

someRouter.get('/', function(req, res) {
  models.article.find(handleDbRes(res))
})

// callback function called at each mongoDB response
var handleDbRes = function(res) {
  return function(err, entries) {
    if (err) {
      err.status = 500;
      return next(err);
    }

    res.json(entries);
  }
};

另一个问题是,handleDbRes()无法访问next,因此您还需要在遇到错误时传递该功能。