Javascript 在另一个查找(…)的回调中查找,如何逃离回调地狱?
(第一:对不起,我英语说得不太好!) 我想返回一个数组中3次查找的结果。 我的代码(下一个)运行得很好,但我陷入了地狱Javascript 在另一个查找(…)的回调中查找,如何逃离回调地狱?,javascript,node.js,callback,mongoose,mean,Javascript,Node.js,Callback,Mongoose,Mean,(第一:对不起,我英语说得不太好!) 我想返回一个数组中3次查找的结果。 我的代码(下一个)运行得很好,但我陷入了地狱 _Schema .static('retrieveAll', function(cb) { query = {}; this.find(query, function(err, data) { if(err) { cb(err, null); return; } if(data)
_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);
});
});
});
});
我有一个发现,一个发现,一个发现。
还有什么可以改进的吗
解决方案:
_模式
.static('retrieveAll',函数(cb){
var模型=此
_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);
});
一些服务器端promise库喜欢并会彻底清理代码,消除回调地狱的混乱。您可以尝试使用 (未经测试)示例: 该示例正在使用,但也有其他promise实现,如和 另外,您可以使用
concat
来连接数组,而不是使用reduce
来查看npm。它是一个可以在node.js上使用的各种模式的强大库
如果存在按时间顺序排列的优先级或模式(如果它们都可以并行执行),则可能需要使用
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);
});
});
}