Ali*_*Ali 6 asynchronous redis node.js
我想问这个问题,因为我不确定我是否正确使用Node.js逻辑
我有一组我需要使用redis'get方法查询的id.并且在检查了某个值之后(假设我正在检查给定"key"的对象是否具有空名称),我将它们添加到列表中.这是我的示例代码;
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");
Run Code Online (Sandbox Code Playgroud)
但正如预期的那样,由于Node的异步特性,如果不检查列表中的每个id,它就会执行"Goes here ...".我需要在检查每个id后应用其余的过程(在redis db中映射并检查名称).但我不知道该怎么做.也许如果我可以将回调附加到for循环并确保我的其余函数在循环结束后开始运行(我知道这是不可能的但只是给出一个想法)?
我会按照您在问题中建议的路线进行操作,并将自定义回调附加到您的提取函数中:
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
});
Run Code Online (Sandbox Code Playgroud)
那可能是最有效的方法。或者,您可以依靠旧的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);
}
});
Run Code Online (Sandbox Code Playgroud)
我们使用process.nextTick而不是实际的方法while来确保在此期间不阻止其他请求;由于Javascript具有单线程特性,因此这是首选方式。为了完整起见,我将其放入其中,但是前一种方法效率更高,并且更适合与node.js配合,因此,除非涉及重大重写,否则请继续进行下去。
两种情况都依赖异步回调是毫无价值的,这意味着它之外的任何代码仍然可以在其他代码完成之前运行。例如,使用我们的第一个片段:
function getStudentsData(callback) {
//[...]
}
getStudentsData(function(dataList) {
//[...]
});
console.log("hello world");
Run Code Online (Sandbox Code Playgroud)
几乎可以保证最后一个console.log在触发传递给getStudentsData的回调之前可以运行。解决方法?为此进行设计,这就是node.js的工作方式。在上面的例子中,这很容易,我们只在传递给getStudentsData的回调中调用console.log ,而不在它之外。其他场景需要的解决方案与传统的过程编码有更多的区别,但是一旦掌握了这一点,您就会发现事件驱动和非阻塞实际上是一个非常强大的功能。
| 归档时间: |
|
| 查看次数: |
9060 次 |
| 最近记录: |