Redis
 sql >> база данни >  >> NoSQL >> Redis

Node.js &Redis; Изчаква се цикълът да завърши

Бих тръгнал по маршрута, който предлагате във вашия въпрос, и бих прикачал персонализирано обратно извикване към вашата функция за извличане:

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, така че го направете, освен ако не е включено сериозно пренаписване.

Нищо не струва, че и двата случая разчитат на асинхронни обратни извиквания, което означава, че всеки код извън него все още може потенциално да се изпълнява, преди другите да са готови. Например, използвайки първия ни фрагмент:

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

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

console.log("hello world");

Този последен console.log е почти гарантирано да работи, преди нашето обратно извикване да премине към getStudentsData да бъде задействано. Заобиколно решение? Проектирайте за него, просто така работи node.js. В нашия случай по-горе е лесно, просто ще извикаме console.log само в нашето обратно извикване се предава на getStudentsData, а не извън него. Други сценарии изискват решения, които се отклоняват малко повече от традиционното процедурно кодиране, но след като се запознаете с него, ще откриете, че управлението на събития и неблокирането всъщност е доста мощна функция.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Как да коригирате ПРЕДУПРЕЖДЕНИЯ при стартиране на изображението на redis:alpine Docker

  2. Транзакционно създаване с валидиране в ServiceStack Redis Client

  3. Достъп до променлива в релсова нишка

  4. Redis Expire не работи

  5. Временна грешка в разделителната способност на името redis