javascript - find内部另一个find(...)的回调,如何逃离回调 hell ?

标签 javascript node.js callback mongoose mean

(首先:对不起,我英语说得不太好!)

我想返回一个数组中 3 个查找结果的结果。 我的代码(下一个)运行良好,但我处于回调 hell 中!

_Schema
  .static('retrieveAll', function(cb) {
    query = {};
    this.find(query, function(err, data) {
      if(err) {
        cb(err, null);
        return;
      }

      if(data)
        all = data;
      else
        all = [];

      _StoresModel.find(query).select('contact address').exec(function(err, data) {
        if(err) {
          cb(err, null);
          return;
        }

        if(data) {
          all = data.reduce(function(coll, item) {
            coll.push(item);
            return coll;
          }, all);
        }

        _CustomersModel.find(query).select('contact address').exec(function(err, data) {
          if(err) {
            cb(err, null);
            return;
          }

          if(data) {
            all = data.reduce(function(coll, item) {
              coll.push(item);
              return coll;
            }, all);
          }

          cb(null, all);          
        });
      });
    });
  });

我有一个 FIND 内的 FIND 内的 FIND 内的 FIND。 有什么办法可以改进吗?

解决方案:

_架构 .static('retrieveAll', 函数(cb) { var 模型 = this;

_async.parallel(
  { contacts: function(cb) {
      model.find({}).exec(cb);
    }
  , stores: function(cb) {
      _StoresModel.find({}).select('contact address').exec(cb);
    }
  , costumers: function(cb) {
      _CostumersModel.find({}).select('contact address').exec(cb);
    }
  }
, function(err, data) {
  if(err) {
    cb(err, null);
    return
  }

  var ret = [];
  if(data.contacts.length > 0) {
    ret = ret.concat(data.contacts);
  }
  if(data.stores.length > 0) {
    ret = ret.concat(data.stores);
  }
  if(data.costumers.length > 0) {
    ret = ret.concat(data.costumers);
  }

  cb(null, ret);
});

最佳答案

您可以尝试使用Promises .

(未经测试)示例:

var RSVP = require('rsvp');
var all = [];

_Schema.static('retrieveAll', function(cb) {
    query = {};

    findPromise(this, query)
    .then(function (data) {
        all = data;
        return findPromise(_StoresModel, query, 'contact address');
    })
    .then(function (stores) {
        all = all.concat(stores);
        return findPromise(_CustomersModel, query, 'contact address');
    })
    .then(function (customers) {
        all = all.concat(customers);
        cb(null, all);
    })
    .catch(function (err) {
        cb(err, null);
    });
});

function findPromise(Model, query, select) {
    return new RSVP.Promise(function (resolve, reject) {
        Model.find(query).select(select || '*').exec(function (err, data) {
            return err ? reject(err) : resolve(data);
        });
    });
}

该示例使用 RSVP ,但还有其他 promise 实现,例如 Qbluebird .

顺便说一句,您可以使用 concat 来连接数组,而不是使用 reduce

关于javascript - find内部另一个find(...)的回调,如何逃离回调 hell ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29383452/

相关文章:

javascript - 检查两次之间的时间间隔

javascript - 未定义不是对象 - Angular $rootScope.user.userMessage

node.js - 如何修复 'Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.'

javascript - 错误 : [undefined] is not a <Route> component. <Routes> 的所有子组件必须是 <Route> 或 <React.Fragment>

javascript - 如何将 javascript 数组转换为在 IE 中工作的 Uint8ClampedArray

node.js - 从 iPhone 浏览本地开发网站

node.js - 在 VS Code 的 NodeJS 应用程序的调试配置中运行 "npm start"

c++ - 有没有办法在不改变参数的情况下改变回调的范围?

带有回调的 Angular @Output

JavaScript 异步回调