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. doRedisは、異なるRedisサーバービルドのWindows8x64でエラーを返します

    2. モンゴのない流星

    3. Javaクライアントを使用したKey-Valueデータベース

    4. mongodbを使用したnodejsでのロック/トランザクションによるドキュメントの読み取りと挿入