sql >> Databáze >  >> NoSQL >> Redis

Node.js &Redis; Čekání na dokončení smyčky

Šel bych cestou, kterou navrhujete ve své otázce, a připojil bych k vaší funkci načítání vlastní zpětné volání:

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

To je pravděpodobně nejúčinnější metoda; alternativně se můžete spolehnout na starou školu while smyčky, dokud nebudou data připravena:

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

Používáme process.nextTick místo skutečného while zajistit, aby mezitím nebyly zablokovány další požadavky; kvůli jednovláknové povaze Javascriptu je to preferovaný způsob. Uvádím to pro úplnost, ale předchozí metoda je efektivnější a lépe se hodí k node.js, takže do toho jděte, pokud nejde o zásadní přepis.

Nestojí za nic, že ​​oba případy se spoléhají na asynchronní zpětná volání, což znamená, že jakýkoli kód mimo něj může stále potenciálně běžet dříve, než budou provedeny ostatní. Např. pomocí našeho prvního úryvku:

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

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

console.log("hello world");

Je téměř zaručeno, že se tento poslední soubor console.log spustí, než bude spuštěno naše zpětné volání předané na getStudentsData. Řešení? Design pro to, node.js prostě funguje. V našem případě výše je to snadné, zavolali bychom pouze console.log pouze v našem zpětném volání předáno getStudentsData a ne mimo něj. Jiné scénáře vyžadují řešení, která se trochu více odchylují od tradičního procedurálního kódování, ale jakmile si to uvědomíte, zjistíte, že řízená událostmi a neblokování je ve skutečnosti docela výkonná funkce.



  1. Snížení velikosti souboru databáze MongoDB

  2. Jak používat MongoRegex (ovladač MongoDB C#)

  3. Redis klíč úložiště bez hodnoty

  4. Přehled vícedokumentových ACID transakcí v MongoDB a jak je používat