在另一个find(...)的回调中查找,如何逃离回调地狱?
Posted
技术标签:
【中文标题】在另一个find(...)的回调中查找,如何逃离回调地狱?【英文标题】:Find inside callback of another find (...), how to escape from callback hell? 【发布时间】:2015-06-05 16:00:13 【问题描述】:(首先:对不起,我的英语不太好!)
我想在一个数组中返回 3 个查找的结果。 我的代码(下一个)运行良好,但我陷入了回调地狱!
_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。 有什么可以改进的吗?
解决方案:
_架构 .static('retrieveAll', function(cb) var model = 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);
);
【问题讨论】:
【参考方案1】:您可以尝试使用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 实现,例如Q 和bluebird。
附带说明,您可以使用concat
来连接数组,而不是使用reduce
。
【讨论】:
【参考方案2】:看看 npm Async。它是一个很棒的库,可以在 node.js 上使用不同的模式。
如果有按时间顺序排列的优先级,您可能希望使用waterfall;如果它们都可以并行执行,您可能希望使用parallel 模式。
【讨论】:
【参考方案3】:q 和 bluebird 等一些服务器端 promise 库会大幅清理您的代码并消除回调地狱的混乱。
【讨论】:
以上是关于在另一个find(...)的回调中查找,如何逃离回调地狱?的主要内容,如果未能解决你的问题,请参考以下文章