I would like to ask this question, because I’m not sure if I got the Node.js logic right
I have a set of id’s that I need to query using redis’ get method. And after checking a certain value(let’s say that im checking whether the object I get with given “key” has a null name), I add them to a list. Here is my example code;
var finalList = [];
var list = [];
redisClient.smembers("student_list", function(err,result){
list = result; //id's of students
console.log(result);
var possibleStudents = [];
for(var i = 0; i < list.length; i++){
redisClient.get(list[i], function(err, result){
if(err)
console.log("Error: "+err);
else{
tempObject = JSON.parse(result);
if(tempObject.name != null){
finalList.push(tempObject);
}
}
});
}
});
console.log("Goes here after checking every single object");
But as expected due to the async nature of Node, without checking every single id in the list it executes the “Goes here…”. My need is to apply the rest of procedures after every id is checked(mapping in redis db and checking the name). But I do not know how to do it. Maybe if I can attach callback to the for loop and assure the rest of my functions start to run after loop is finished(i know it’s impossible but just to give an idea)?
I would go the route you suggest in your question and attach a custom callback to your fetching function:
That’s probably the most efficient method; alternatively you could rely on an old school
whileloop until the data is ready:We use
process.nextTickinstead of an actualwhileto make sure other requests are not blocked in the meantime; due to the single threaded nature of Javascript this is the preferred way. I’m throwing this in for the sake of completeness, but the former method is more efficient and fits better with node.js, so go for it unless a major rewrite is involved.It’s worth nothing that both cases rely on async callbacks, which means any code outside it can still potentially run before others are done. E.g., using our first snippet:
That last console.log is almost guaranteed to run before our callback passed to getStudentsData gets fired. Workaround? Design for it, it’s just how node.js works. In our case above it’s easy, we just would call console.log only in our callback passed to getStudentsData and not outside it. Other scenarios require solutions that depart a bit more from traditional procedural coding, but once you get your head around it you’ll find being event-driven and non-blocking is actually a pretty powerful feature.