私はあなたがあなたの質問に提案するルートを行くと、あなたのフェッチ機能にカスタムコールバックを添付します:おそらく最も効率的な方法だ
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
});
。データの準備ができるまで、その代わりに、あなたは古い学校while
ループに頼ることができる:
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);
}
});
我々はその間にブロックされていないことを確認、他の要求を作成する代わりに、実際のwhile
のprocess.nextTick
を使用します。 Javascriptのシングルスレッドの性質のため、これが好ましい方法です。私は完全性のためにこれを投げていますが、前者の方法はnode.jsのほうが効率的で、うまく適合していますので、大規模な書き換えが含まれていない限り行ってください。
両方のケースが非同期コールバックに依存することは何も価値がありません。つまり、その外部のコードは、他のコードが実行される前に実行される可能性があります。例えば、私たちの最初のスニペットを使用して:
function getStudentsData(callback) {
//[...]
}
getStudentsData(function(dataList) {
//[...]
});
console.log("hello world");
最後にconsole.logをほぼgetStudentsDataに渡された私たちのコールバックが発射される前に実行することが保証されていること。回避策?これを設計すると、node.jsの動作だけです。上のケースでは簡単ですが、console.log と呼び出すのは、コールバックののみがgetStudentsDataに渡され、その外にはありません。他のシナリオでは、伝統的な手続き型コーディングから少し離れたソリューションが必要です。しかし、一度それを取り巻くと、イベント駆動型であり、非ブロッキングは実際には非常に強力な機能です。
最初の例は私のために動作するようには思えない:(参照[この](https://i.gyazo.com/129b071f39bbd1a1c491638be634b00c.png)、Redisの呼び出しは非同期であるザ・が。 –