복붙노트

[REDIS] Node.js를 & 레디 스; 끝까지 루프를 기다리는 중

REDIS

Node.js를 & 레디 스; 끝까지 루프를 기다리는 중

잘 모르겠어요 때문에 나는 Node.js를 논리 권리를 가지고 있다면,이 질문을하고 싶습니다

나는 ID의 집합 내가 레디 스 'get 메소드를 사용하여 쿼리에 필요하다고입니다 있습니다. 그리고 특정 값을 확인 후, 나는 그들이 목록에 추가 (의 내가 주어진 "키"로 얻을 객체가 null의 이름이 있는지 여부를 그 메신저 검사를 가정 해 봅시다). 여기 내 예제 코드입니다;

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

목록에있는 모든 단일 ID를 확인하지 않고, 노드의 비동기 특성으로 인해 예상대로하지만 그것은이 "여기 간다 ..."실행합니다. 내 필요가 모든 ID가 (레디 스 DB에 매핑 및 이름을 확인)를 확인 후 절차의 나머지를 적용하는 것입니다. 그러나 나는 그것을하는 방법을 모르겠어요. 내가 for 루프에 콜백을 연결하고 내 기능의 나머지 부분은 루프가 완료된 후 실행을 시작 드릴 수 있습니다 아마도 경우 (내가 그것을 불가능 알고 있지만 단지 아이디어를 제공하기 위해)?

해결법

  1. ==============================

    1.나는 당신이 당신의 질문에 제안하고 가져 오는 기능에 사용자 정의 콜백을 연결 경로를 갈 것입니다 :

    나는 당신이 당신의 질문에 제안하고 가져 오는 기능에 사용자 정의 콜백을 연결 경로를 갈 것입니다 :

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

    그건 아마도 가장 효율적인 방법이다; 데이터까지 루프가 준비되는 동안 또는 당신은 오래된 학교에 의지 할 수 있었다 :

    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를 사용; 때문에 자바 스크립트의 단일 스레드 특성이 선호하는 방법입니다. 나는 완전성을 위해서이 던지는거야하지만, 전자의 방법은 주요 재 작성이 관련되지 않는 이상 그것을 위해 이동 맞는 더 나은 Node.js를 더 효율적이고.

    이 두 경우 모두 다른 사람이 완료되기 전에 외부의 코드는 여전히 잠재적으로 실행할 수 있습니다 즉, 비동기 콜백에 의존 가치가 아무것도 아니다. 예를 들어, 첫 번째 조각을 사용하여 :

    function getStudentsData(callback) {
        //[...]
    }
    
    getStudentsData(function(dataList) {
        //[...]
    });
    
    console.log("hello world");
    

    마지막 CONSOLE.LOG 거의 getStudentsData에 전달 우리의 콜백 해고되기 전에 실행되도록 보장됩니다. 해결 방법? 이 작품을 Node.js를 어떻게 그냥, 그것을 위해 디자인합니다. 우리의 경우는 쉽게 위에, 우리는 우리의 콜백이 외부 getStudentsData에 전달뿐만 아니라에서 CONSOLE.LOG 부를 것이다. 다른 시나리오보다 코딩 전통적인 절차에서 약간의 출발 솔루션을 필요로하지만, 당신이 주위에 당신의 머리를 일단 당신은 이벤트 기반 및 비 차단 실제로 매우 강력한 기능입니다 것을 찾을 수 있습니다.

  2. ==============================

    2.마무리 모듈을보십시오. 나는이 문제를 해결하기 위해이 모듈을 만들었습니다. 비동기보다 사용하기 쉽고, 또한 더 나은 성능을 얻을 수 있습니다. 다음은 그 예이다 :

    마무리 모듈을보십시오. 나는이 문제를 해결하기 위해이 모듈을 만들었습니다. 비동기보다 사용하기 쉽고, 또한 더 나은 성능을 얻을 수 있습니다. 다음은 그 예이다 :

    var finish = require("finish");
    finish(function(async) { 
      // Any asynchronous calls within this function will be captured
      // Just wrap each asynchronous call with function 'async'
      ['file1', 'file2', 'file3'].forEach(function(file) {
        async(function(done) { 
          // Your async function should use 'done' as callback, or call 'done' in its callback
          fs.readFile(file, done); 
        });
      });
    }, function(err, results) {
      // fired after all asynchronous calls finish or as soon as an error occurs
      console.log(results[0]);console.log(results[1]);console.log(results[2]);
    });
    
  3. ==============================

    3.node.js.에 대한 비동기 모듈을보십시오 그 모듈은 비동기 대해 forEach있다.

    node.js.에 대한 비동기 모듈을보십시오 그 모듈은 비동기 대해 forEach있다.

  4. from https://stackoverflow.com/questions/12819610/node-js-redis-waiting-for-a-loop-to-finish by cc-by-sa and MIT license