Reputation: 5192
In my node app i am using async.series for executing 3 queries its executed very well.. But in my 3rd query execution i have to execute another query based on result of 3rd query its also working fine. But t i executing some logic in the third query so after all gets completed only i have to call callback....
My code:
async.series({
levels: function(cb) {
sequelize.query("select country_id, country_name, level0, level1, level2, level3, level4 from levels").success(function(levelsResults) {
levelsResult = levelsResults;
cb(null, levelsResult);
})
},
level1: function(cb) {
sequelize.query("select id_0, name_0, name_1 from xxxxx group by id_0, name_0, name_1").success(function(level1Result) {
level1result = level1Result;
cb(null, level1result);
})
},
keys: function(cb) {
sequelize.query("select id_0 from xxxx group by id_0").success(function(id_0Result) {
var obj = {};
for (var i = 0; i < id_0Result.length; i++) {
sequelize.query("select id_0, value->>'yyyy' as value from xxxx where id_0 = " + id_0Result[i].id_0 + " limit 1").success(function(keyResult) {
var keyArray = [];
var keysObjectArray = [];
id_0 = keyResult[0].id_0;
keyResult = keyResult[0].value;
keyResult = JSON.parse(keyResult);
for (var prop in keyResult) {
keyArray.push(prop)
}
obj["" + id_0 + ""] = keyArray;
keysObjectArray.push(obj);
cb(null, keysObjectArray);
---.my problem is here cb is called in the 1st iteration of
for loop.It should be called after loop finishes
})
}
})
}
}, function seriesFinal(seriesErr, seriesResults) {
if (seriesErr) throw new Error("Something bad!");
onSuccess(JSON.stringify(seriesResults), callback);
});
My result is:
{"levels":[{levsls}],"level1":[{level1}],"keys":[{}]};
but what i am expecting is:
{"levels":[{levsls}],"level1":[{level1}],"keys":[{},{}]};
EDIT:
Simply how can i make the sequlize query to execute for loop and finally have to call the callback
Help me to solve this..Thanks in advance.....
Upvotes: 0
Views: 305
Reputation: 24948
There's more to async than just async.series
! You can use async.forEach
to do loops, and for your keys
function, async.map
will do nicely:
keys: function(cb) {
sequelize.query("select id_0 from xxxx group by id_0").success(function(id_0Result){
var obj = {};
// Loop over each object in id_0Result,
// and transform it into a new array
async.map(
id_0Result,
function(result, cb) {
sequelize.query("select id_0, value->>'yyyy' as value from xxxx where id_0 = "+result.id_0+" limit 1").success(function(keyResult){
var keyArray=[];
id_0 = keyResult[0].id_0;
keyResult = keyResult[0].value;
keyResult = JSON.parse(keyResult);
for (var prop in keyResult){
keyArray.push(prop)
}
obj[""+id_0+""] = keyArray;
// Add this object to the array result for async.map
return cb(null, obj);
})
},
// Call the callback for async.series with the result of
// the mapping; effectively cb(null, transformedArray)
cb
);
});
}
Upvotes: 1
Reputation: 2518
The "for" loop runs "n" queries which callbacks randomly the "success" function.
You can use a counter to make sure that all your queries called back
sequelize.query("select id_0 from xxxx group by id_0").success(function(id_0Result){
var obj = {};
var counter = 0;
for(var i=0; i<id_0Result.length; i++){
sequelize.query("select id_0, value->>'yyyy' as value from xxxx where id_0 = "+id_0Result[i].id_0+" limit 1").success(function(keyResult){
var keyArray=[];
var keysObjectArray =[];
id_0 = keyResult[0].id_0;
keyResult = keyResult[0].value;
keyResult = JSON.parse(keyResult);
for (var prop in keyResult){
keyArray.push(prop)
}
obj[""+id_0+""] = keyArray;
keysObjectArray.push(obj);
counter +=1;
if(counter === id_0Result.length )
{
cb(null, keysObjectArray);
}
})
}
Note that the order in keysObjectArray is random as are the callbacks.
Hope it helps.
Yoann
Upvotes: 1