I have this case where I have a lot of data I need to sort into different buckets. If there's already a bucket for a certain data type then push it in there, but if the encountered data type is new I need to make a new bucket for it which requires a DB query. This works fine in theory. But, the problem I have is the DB queries need to happen before the loop continues so future data can be inserted into that bucket. How can I pause a loop until a function finishes?
I've tried the loop and callback approach and I get the control flow I'm looking for, but the data is too large and I stack overflow. Is there another way solve this control flow?
EDIT: Added code with promises like people suggested. It actually works well, but just stops at data point 8428. As far as I can tell that data point isn't special and all the buckets have been created at that point so its not creating a new bucket. It just stops. Any ideas? Maybe its how I call next() and I'm missing a case?
async function sortData(data, images, i) {
let uuidList = [];
//This loop will wait for each next() to pass the next iteration
for (var j = 0; j < data.length; ++j) {
await new Promise(next=> {
let pos = uuidList.map(function(e) { return e.uuid; }).indexOf(data[j].uuid);
if(pos < 0){
Instance_Type.findInstance(data[j]._instance_type, function(err, instance){
/* add new bucket here */
if(itemsProcessed == images.length) {
processBuckets(uuidList, threshold, function(){
console.log("Bucket finished");
dataPackage.push({
imageName: images[i].name,
uuidList: uuidList,
});
++itemsProcessed;
if(itemsProcessed == images.length){
console.log("Rendering!");
res.render('data', {
dataPackage: dataPackage
});
}
});
}
next();
});
} else {
/*push to existing bucket here*/
if(itemsProcessed == images.length) {
processBuckets(uuidList, threshold, function(){
console.log("Bucket finished");
dataPackage.push({
imageName: images[i].name,
uuidList: uuidList,
});
++itemsProcessed;
console.log(itemsProcessed);
if(itemsProcessed == images.length){
console.log("Rendering!");
res.render('data', {
dataPackage: dataPackage
});
}
});
}
next();
}
})
}
}