我在将PHP同步代码翻译到Node时遇到了一个小问题。
PHP
$bodies = getBodystyles();
foreach($bodies as $b) {
$aCar['body'] = $b['Body'];
$code = getCode($aCar);
$promo = checkPromotionByCarID($code['Car']);
}
我试着用这种方式转换:
节点
db.getBodystyles(function(err, bodies){
for (b in bodies) {
console.log(bodies[b]);
var aCar = Common.ConfiguratorDefault;
db.getCode(aCar, function(err, code){
console.log(code);
bodies[b].aCar = aCar;
bodies[b].code = code;
// checkPromotionByCarID here?
});
}
options.bodies = bodies;
showView(options);
});
但是使用此代码showView在getCode调用完成之前运行。
做这件事的正确方法是什么?如有任何帮助,将不胜感激
更新我看到这个问题被标记为重复。建议的副本在这里然而,提出的问题并不能解决我的问题。我需要在循环完成后以及循环内的所有异步调用完成后执行一个函数(showView)。
我从数据库上的Select开始,对于结果的每个元素,我需要执行另外两个查询。只有在查询完成后,我才需要执行我的功能,但我不明白如何执行,而且建议的问题并不能解决我的需求。
根据建议,我的问题的解决方案是通过Async或Rsvp库获得的。
以下是两种可能的解决方案:
ASYNC
使用Async.js
db.getBodystyles(function(err, bodies){
async.each(bodies, function( b, callback) {
var aCar = Common.ConfiguratorDefault;
aCar.body = b.Body;
db.getCode(aCar, function(err, code){
if (err){
callback(err);
}else{
b.aCar = aCar;
b.code = code;
db.checkPromotionByCarID(code.Car, function(err, promo){
if (err){
callback(err);
}else{
b.promo = promo;
callback();
}
});
}
});
},function(err){
if( err ) {
console.log('A file failed to process');
res.render('500');
} else {
console.log('All files have been processed successfully');
options.bodies = bodies;
showView(options);
}
});
});
RSVP
使用Rsvp.js
db.getBodystyles(function(err, bodies){
var promises = bodies.map(function(b) {
var aCar = Common.ConfiguratorDefault;
aCar.body = b.Body;
var promise = new RSVP.Promise(function(resolve, reject) {
db.getCode(aCar, function(err, code){
if(err) reject(err);
b.aCar = aCar;
b.code = code;
db.checkPromotionByCarID(code.Car, function(err, promo){
if(err) reject(err);
b.promo = promo;
resolve();
});
});
});
return promise;
};
RSVP.all(promises).then(function() {
options.bodies = bodies;
showView(options);
}).catch(function(err) {
throw err;
});
});