Reputation: 265
everyone. I am doing an application that adds and updates fileds in database. My problem is that my loop continues even though database updating calls still not yet successfully finished. How can I manage to make for loop wait unit those functions finish before continuing the loop?
Any help will be appreciated.
Here is this piece of code:
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);
});
}
});
}
Upvotes: 0
Views: 67
Reputation: 1639
I advise using some library when you need to do asynchronous things. I wrote a small example based in your code using when, you can see all methods 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")
})
You also can use native promises: Promise.all
Upvotes: 2
Reputation: 2825
I will go and shamelessly advertise our own library called Coastline. The code would look something like this.
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()));
}
});
The library will wait for all CL.bg()
calls to finish before running the next CL.each()
iteration. You can replace CL.bg()
with yield
for everything to execute in sequence inside the iteration.
Upvotes: 1