循环内的节点和异步调用

时间:2014-09-11 14:35:05

标签: javascript php node.js asynchronous

我有一个问题,即将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);
});

但是在getCode调用完成之前运行此代码 showView

这样做的正确方法是什么? 任何帮助将不胜感激

更新 我看到这个问题被标记为重复。 The suggested duplicate are here 然而,提出的问题并没有解决我的问题。 我需要在循环完成后以及循环内的所有异步调用完成后执行一个函数(showView)。

我从Select on DB开始,对于每个结果元素,我需要执行其他两个查询。 只有在查询完成后我才需要执行我的功能,我不明白这是怎么做的,而且提出的问题并不能解决我的需要。

1 个答案:

答案 0 :(得分:0)

如建议的那样,我的问题的解决方案是通过库异步 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;
  });
});