sql >> Databasteknik >  >> NoSQL >> Redis

Node.js &Redis; Väntar på att en loop ska sluta

Jag skulle gå den väg du föreslår i din fråga och bifoga en anpassad återuppringning till din hämtningsfunktion:

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

Det är förmodligen den mest effektiva metoden; alternativt kan du lita på en gammal skola while loop tills data är klar:

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

Vi använder process.nextTick istället för en faktisk while för att se till att andra förfrågningar inte blockeras under tiden; På grund av Javascripts enkeltrådade natur är detta det föredragna sättet. Jag slänger in det här för fullständighetens skull, men den förstnämnda metoden är effektivare och passar bättre med node.js, så kör på det om inte en större omskrivning är inblandad.

Det är ingenting värt att båda fallen förlitar sig på asynkrona återuppringningar, vilket innebär att all kod utanför den fortfarande kan köras innan andra är klara. Till exempel genom att använda vårt första utdrag:

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

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

console.log("hello world");

Den sista console.log kommer nästan garanterat att köras innan vår callback skickas till getStudentsData avfyras. Jobba runt? Design för det, det är bara hur node.js fungerar. I vårt fall ovan är det enkelt, vi skulle bara kalla console.log endast i vår callback skickas till getStudentsData och inte utanför den. Andra scenarier kräver lösningar som avviker lite mer från traditionell procedurkodning, men när du väl har bestämt dig för det kommer du att upptäcka att vara händelsestyrd och att icke-blockerande faktiskt är en ganska kraftfull funktion.



  1. MongoDB Object.bsonSize()

  2. Vilka är de underliggande datastrukturerna som används för Redis?

  3. Returnera det senaste dokumentet från en uppslagning

  4. Bulk upsert i MongoDB med mongoose