Saya akan mengikuti rute yang Anda sarankan dalam pertanyaan Anda dan melampirkan panggilan balik khusus ke fungsi pengambilan Anda:
function getStudentsData(callback) {
var setList = [];
var dataList = [];
redisClient.smembers("student_setList", function(err,result) {
setList = result; //id's of students
for(var i = 0; i < setList.length; i++) {
redisClient.get(setList[i], function(err, result) {
if(err) {
console.log("Error: "+err);
} else {
tempObject = JSON.parse(result);
if(tempObject.name != null) {
dataList.push(tempObject);
}
}
});
}
if(dataList.length == setList.length) {
if(typeof callback == "function") {
callback(dataList);
}
console.log("getStudentsData: done");
} else {
console.log("getStudentsData: length mistmach");
}
});
}
getStudentsData(function(dataList) {
console.log("Goes here after checking every single object");
console.log(dataList.length);
//More code here
});
Itu mungkin metode yang paling efisien; sebagai alternatif, Anda dapat mengandalkan while
sekolah lama loop sampai data siap:
var finalList = [];
var list = [0];
redisClient.smembers("student_list", function(err,result) {
list = result; //id's of students
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);
}
}
});
}
});
process.nextTick(function() {
if(finalList.length == list.length) {
//Done
console.log("Goes here after checking every single object");
console.log(dataList.length);
//More code here
} else {
//Not done, keep looping
process.nextTick(arguments.callee);
}
});
Kami menggunakan process.nextTick
alih-alih while
yang sebenarnya untuk memastikan permintaan lain tidak diblokir sementara itu; karena sifat Javascript berulir tunggal, ini adalah cara yang disukai. Saya memasukkan ini demi kelengkapan, tetapi metode sebelumnya lebih efisien dan lebih cocok dengan node.js, jadi lakukanlah kecuali jika ada penulisan ulang besar yang terlibat.
Tidak ada gunanya kedua kasus bergantung pada panggilan balik async, yang berarti kode apa pun di luarnya masih berpotensi berjalan sebelum yang lain selesai. Misalnya, menggunakan cuplikan pertama kami:
function getStudentsData(callback) {
//[...]
}
getStudentsData(function(dataList) {
//[...]
});
console.log("hello world");
Console.log terakhir itu hampir dijamin berjalan sebelum panggilan balik kami diteruskan ke getStudentsData dipecat. Solusi? Rancang untuk itu, begitulah cara kerja node.js. Dalam kasus kami di atas mudah, kami hanya akan memanggil console.log saja dalam panggilan balik kami diteruskan ke getStudentsData dan bukan di luarnya. Skenario lain memerlukan solusi yang sedikit berbeda dari pengkodean prosedural tradisional, tetapi setelah Anda memahaminya, Anda akan menemukan bahwa menjadi event-driven dan non-blocking sebenarnya adalah fitur yang cukup kuat.