node.js中数据库函数的同步执行

时间:2016-01-27 06:41:35

标签: node.js mongodb synchronous

我的数据库中有两个产品系列和库存。每个产品都有多种产品,产品的供应商和属性不同。 我从产品系列中选择了产品并为每个产品运行一个循环。我需要将库存集中的价格和报价附加到我已经选择的产品上。 我认为for循环在执行库存集合上的find方法之前完成了它的执行。我需要以串行方式执行循环中的所有内容(非异步)。请检查下面的代码并帮我解决这个问题。我是node.js和mongodb的新手

collection  = db.collection('products');
collection.find().toArray(function(err, abc) {
var finalout = [];
        for( var listProducts in abc){
               var subfinal = {
                 '_id'          :abc[listProducts]['_id'],
                 'min_price'    :abc[listProducts]['value']['price'],
                 'stock'        :abc[listProducts]['value']['stock'],
                 'name'         :abc[listProducts]['value']['name'],
                 'price'        :'',
                 'offer_price'  :'',
               };
               collection  = db.collection('stock');
               collection.find({"product":abc[listProducts]['_id'] ,"supplier":abc[listProducts]['value']['def_supplier']}).toArray(function(err, newprod) {
                  for( var row in newprod){
                       subfinal['price']      =   newprod[row]['price'];
                       subfinal.offer_price   =   newprod[row]['offer_price']; 
                   }
                   finalout.push(subfinal);
             });
        }
        console.log(finalout);
  });

1 个答案:

答案 0 :(得分:0)

是的,循环正在运行并同时在数据库上启动get请求。像你说的那样,有可能按顺序运行它们,但它可能不是你想要的。这样做会花费更多的时间,因为对Mongo的每个请求都需要等待前一个请求完成。

考虑到循环的每次迭代都不依赖于之前的迭代,所有你真正想要的是一旦所有操作都完成就知道了。请记住,这些可以以任何顺序结束,不一定是它们在循环中启动的顺序。

创建subfinal变量时也存在问题。由于所有迭代都使用相同的变量名称,当它们全部返回时,它们将使用变量的最终赋值(所有结果将写在同一subfinal上,这将被多次推送进入结果)。为了解决这个问题,我将整个项目处理迭代包装到另一个函数中,为每个subfinal变量赋予它自己的范围。

plenty of modules来简化这种管理,但是这里只有在使用不需要任何额外安装的计数器和回调完成所有Mongo调用之后运行某些代码的方法之一:

var finished = 0; // incremented every time an iteration is done
var total = Object.keys(abc).length; // number of keys in the hash table

collection  = db.collection('products');
collection.find().toArray(function(err, abc) {
    var finalout = [];

    for( var listProducts in abc){
        processItem(listProducts);
    }

});


function processItem(listProducts) {
    var subfinal = {
        '_id'          :abc[listProducts]['_id'],
        'min_price'    :abc[listProducts]['value']['price'],
        'stock'        :abc[listProducts]['value']['stock'],
        'name'         :abc[listProducts]['value']['name'],
        'price'        :'',
    'offer_price'  :'',
    };
    collection  = db.collection('stock');
    collection.find({"product":abc[listProducts]['_id'] ,"supplier":abc[listProducts]['value']['def_supplier']}).toArray(function(err, newprod) {
        for( var row in newprod){
            subfinal['price']      =   newprod[row]['price'];
            subfinal.offer_price   =   newprod[row]['offer_price']; 
        }
        finalout.push(subfinal);
        finished++;
        if (finished === total) { // if this is the last one to finish.
            allFinished(finalout);
        }
    });
}


function allFinished(finalout) {
    console.log(finalout);
}

可以用更少的变量更简洁地编写,但这样更容易理解。