gpt4 book ai didi

Node.js 和 Redis;等待循环结束

转载 作者:IT王子 更新时间:2023-10-29 05:57:53 25 4
gpt4 key购买 nike

我想问这​​个问题,因为我不确定我的 Node.js 逻辑是否正确

我有一组 id,需要使用 redis 的 get 方法查询。在检查了某个值之后(假设我正在检查我使用给定“键”获得的对象是否具有空名称),我将它们添加到列表中。这是我的示例代码;

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");

但正如预期的那样,由于 Node 的异步特性,它没有检查列表中的每个 id,而是执行“Goes here...”。我的需要是在检查每个 id 后应用其余过程(在 redis 数据库中映射并检查名称)。但我不知道该怎么做。也许如果我可以将回调附加到 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
});

这可能是最有效的方法;或者,您可以依赖老派的 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);
}
});

我们使用 process.nextTick 而不是实际的 while 来确保其他请求不会同时被阻止;由于 Javascript 的单线程特性,这是首选方式。为了完整起见,我将其放入,但前一种方法更有效并且更适合 node.js,所以除非涉及重大重写,否则请继续使用。

这两种情况都依赖于异步回调,这毫无值(value),这意味着它之外的任何代码仍然有可能在其他代码完成之前运行。例如,使用我们的第一个片段:

function getStudentsData(callback) {
//[...]
}

getStudentsData(function(dataList) {
//[...]
});

console.log("hello world");

最后一个 console.log 几乎可以保证在传递给 getStudentsData 的回调被触发之前运行。解决方法?为其设计,这就是 node.js 的工作方式。在我们上面的例子中,这很简单,我们只需在传递给 getStudentsData 的回调中调用 console.log ,而不是在它之外。其他场景需要与传统过程编码有更多不同的解决方案,但一旦您了解它,您就会发现事件驱动和非阻塞实际上是一个非常强大的功能。

关于Node.js 和 Redis;等待循环结束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12819610/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com