【问题标题】:How to make for loop to do all functions before next iteration in Node.js如何在 Node.js 中的下一次迭代之前使 for 循环执行所有功能
【发布时间】:2016-08-11 00:30:38
【问题描述】:

每个人。我正在做一个在数据库中添加和更新文件的应用程序。 我的问题是,即使数据库更新调用仍未成功完成,我的循环仍在继续。 在继续循环之前,我如何设法使这些函数完成循环等待单元?

我们将不胜感激。

这是这段代码:

for(i = 0; i < treatments.length; i++) {
    collection3.find({"_id": parseInt(treatments[i])}).toArray(function(err, results) {
    if(results[0].maxPrice < parseInt(treatmentsPrices[i])){
        collection3.update({"_id": parseInt(treatments[i])}, {"maxPrice": parseInt(treatmentsPrices[i])}, function(err, success) {
            counter++;
            console.log(err);
        });
    }
    if(results[0].minPrice > parseInt(treatmentsPrices[i])){
        collection3.update({"_id": parseInt(treatments[i])}, {"minPrice": parseInt(treatmentsPrices[i])}, function(err, success) {
            console.log(err);
        });
    }
    collection3.update({"_id": parseInt(treatments[i])}, {$addToSet: {"doctors": parseInt(doctorId)}}, function(err, success) {
        console.log(err);
    });
    collection3.update({"_id": parseInt(treatments[i])}, {$addToSet: {"hospitals": parseInt(hospitals[i])}}, function(err, success) {
        console.log(err);
    });
    if(newHospitalName != null) {
        collection3.update({"_id": parseInt(treatments[i])}, {$addToSet: {"hospitals": parseInt(hospitalId)}}, function(err, success) {
            console.log(err);
        });
    }
    });                         
}

【问题讨论】:

    标签: node.js mongodb for-loop asynchronous


    【解决方案1】:

    我建议您在需要执行异步操作时使用一些库。 我使用when在您的代码中编写了一个小示例,您可以看到所有方法here

    var when = require('when');
    var promises = [];
    
    var treatmentsUpdater = function (opts) {
      var treatments = opts.treatments;
      var treatmentsPrices = opts.treatmentsPrices;
      var doctorId = opts.doctorId
      var hospitals = opts.hospitals;
      var hospitalId = opts.hospitalId
    
      collection3.find({"_id": parseInt(treatments[i])}).toArray(function(err, results) {
        if(results[0].maxPrice < parseInt(treatmentsPrices[i])){
          collection3.update({"_id": parseInt(treatments[i])}, {"maxPrice": parseInt(treatmentsPrices[i])}, function(err, success) {
            counter++;
            console.log(err);
          });
        }
        if(results[0].minPrice > parseInt(treatmentsPrices[i])){
          collection3.update({"_id": parseInt(treatments[i])}, {"minPrice": parseInt(treatmentsPrices[i])}, function(err, success) {
            console.log(err);
          });
        }
        collection3.update({"_id": parseInt(treatments[i])}, {$addToSet: {"doctors": parseInt(doctorId)}}, function(err, success) {
          console.log(err);
        });
        collection3.update({"_id": parseInt(treatments[i])}, {$addToSet: {"hospitals": parseInt(hospitals[i])}}, function(err, success) {
          console.log(err);
        });
        if(newHospitalName != null) {
          collection3.update({"_id": parseInt(treatments[i])}, {$addToSet: {"hospitals": parseInt(hospitalId)}}, function(err, success) {
            console.log(err);
          });
        }
      });
    }
    
    for(i = 0; i < treatments.length; i++) {
      var opts = {
        treatments: treatments[i],
        treatmentsPrices: treatmentsPrices[i],
        doctorId: doctorId,
        hospitals: hospitals[i],
        hospitalId: hospitalId
      }
      promises.push(treatmentsUpdater(opts))   
    }
    
    when.all(promises).then(function () {
      console.log("The database has been updated")
    })

    您也可以使用原生承诺:Promise.all

    【讨论】:

      【解决方案2】:

      我会去无耻地宣传我们自己的图书馆Coastline。代码看起来像这样。

      CL.each(treatments, function* (treatment, i) {
        
        var results = yield collection3.find({"_id": parseInt(treatment)}).toArray(CL.cb());
        
        if (results[0].maxPrice < parseInt(treatmentsPrices[i])) {
          CL.bg(collection3.update({"_id": parseInt(treatment)}, {"maxPrice": parseInt(treatmentsPrices[i])}, CL.cb()));
        }
        if(results[0].minPrice > parseInt(treatmentsPrices[i])) {
          CL.bg(collection3.update({"_id": parseInt(treatment)}, {"minPrice": parseInt(treatmentsPrices[i])}, CL.cb()));
        }
                             
        CL.bg(collection3.update({"_id": parseInt(treatment)}, {$addToSet: {"doctors": parseInt(doctorId)}}, CL.cb()));
        
        CL.bg(collection3.update({"_id": parseInt(treatment)}, {$addToSet: {"doctors": parseInt(doctorId)}}, CL.cb()));
        
        CL.bg(collection3.update({"_id": parseInt(treatment)}, {$addToSet: {"hospitals": parseInt(hospitals[i])}}, CL.cb()));
        
        if(newHospitalName != null) {
          CL.bg(collection3.update({"_id": parseInt(treatment)}, {$addToSet: {"hospitals": parseInt(hospitalId)}}, CL.cb()));
        }
        
      });

      库将等待所有CL.bg() 调用完成,然后再运行下一次CL.each() 迭代。您可以将CL.bg() 替换为yield,以便在迭代中按顺序执行所有内容。

      【讨论】:

      • 函数后面的这个'*'是干什么用的?我收到了意外的令牌错误。
      • 这是一个生成器函数developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…*你使用的是哪个版本的Node?​​span>
      • 好的,我找到了。我必须有 0.12 才能使用它并使用标志 --harmony_generators 运行它。我说的对吗?
      猜你喜欢
      • 2016-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-02
      • 2015-05-12
      • 1970-01-01
      • 2014-07-30
      • 2020-07-17
      相关资源
      最近更新 更多