You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB7升级后Mongoose中_.bind回调报错的解决问询

解决MongoDB 7升级后Mongoose回调兼容问题

升级MongoDB 7后,Mongoose移除了对query.exec()回调参数的支持,原代码中_.bind(query.exec, query)触发"no longer accepts a callback function"异常。尝试改用Promise链式调用时,因未正确传递查询结果给sendData导致逻辑失效。

原错误代码

return _.bind(function(req, res, next) {
  var query = this.getQuery(req);
  async.waterfall([
    _.bind(query.exec, query),
  ], this.sendData(req, res, next));
}, this);

原sendData函数

sendData: function(req, res, next) {
   var fields = _parseJSON(req.query.fields, []), optFields;
   if (!_.isArray(fields)) {
      fields = [fields];
   }
  function _sendData(err, data) {
    if (err) {
      res.json({'data':data,'error':err}); 
    } else {
      res.json(data);
    }
  }
  fields = _.intersection(fields, this.model.optionalFields);
  return function(err, data) {
    if (fields.length > 0) {
     var isArray = _.isArray(data);
     async.map(isArray ? data : [data], function(doc, callback) {
      var obj = doc.toObject();
      async.each(fields, function(field, cb) {
        doc['get' + field].call(doc, function(err, value) {
          obj[field] = value;
          cb(err);
        });
      }, function(err) {
        callback(err, obj);
      });
    }, function(err, objs) {
      return _sendData(err, isArray ? objs : objs[0]);
    });
  } else {
    _sendData(err, data);
  }
};

解决方案

sendData返回的是一个接收(err, data)参数的回调函数,因此需要将query.exec()返回的Promise结果适配到该格式,同时确保this上下文正确:

方式1:Promise链式调用

return _.bind(function(req, res, next) {
  var query = this.getQuery(req);
  query.exec()
    // 查询成功时,传入null(无错误)和结果给sendData的回调
    .then(result => this.sendData(req, res, next)(null, result))
    // 查询失败时,传入错误和null给回调
    .catch(err => this.sendData(req, res, next)(err, null));
}, this);

方式2:async/await(更易读)

return _.bind(async function(req, res, next) {
  var query = this.getQuery(req);
  try {
    const result = await query.exec();
    this.sendData(req, res, next)(null, result);
  } catch (err) {
    this.sendData(req, res, next)(err, null);
  }
}, this);

关键说明

之前的改写失效原因是仅调用了this.sendData(req, res, next),但未将查询结果作为参数传递给它返回的回调函数。sendData本身是一个工厂函数,返回的才是真正处理数据的逻辑函数,必须传入err和data参数才能触发后续的字段处理和响应发送逻辑。

内容的提问来源于stack exchange,提问作者peter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 03:05:09