2

redis 데이터 저장소에서 키 목록을 가지고 있는데, 키 목록을 반복하고 해당 값을 redis에서 가져 오려고합니다. 캐치 내가 이렇게 .. 자바 스크립트 절차 있다면 나는 내가 할 수없는이루프 오버 이벤트 기반 코드?

function getAll(callback) { 
    var list = redis.lrange(lrange('mykey', 0, -1); 
    for (var i = 0; i < list.length; i+= 1) { 
     list[i] = redis.hgetall(list[i]); 
    } 
    callback(list); 
} 

을하지만 수 Node.js를

를 통해 이벤트 중심의 언어, 자바 스크립트를 사용하고있다, 그 때문에?

function getAll(callback) { 
    redis.lrange('mykey', 0, -1, function(err, reply) { 
     // convert reply into messages 
     var list = []; 
     var index = -1; 
     var recurse = function() { 
      if (index == reply.length) { 
       callback(list); 
      } else { 
       redis.hgetall(reply[i], function(err, reply) { 
        list.push(reply); 
        index += 1; 
        recurse(); 
       }); 
      } 
     }; 
     recurse() 
    }); 
}; 

이 있기 때문에, 대신 한 번에 모든 요청을 실행하고 나는 연속 호출 순서를 강제하고, 콜백리스트에 삽입시키는의 잘못 솔기. 1000s의 키가 있다면 어떻게됩니까?

어떻게하면 되나요?

function getAll(callback) { 
    redis.lrange('mykey', 0, -1, function(err, reply) { 

     // convert reply into messages 
     var list = []; 
     var insert = function(err, reply) { 
      list.push(reply); 
     }; 
     for (var i = 0; i < reply.length; i += 1) { 
      redis.hgetall(reply[i], insert); 
     } 

     ??? how to block until finished ??? 
     callback(list); 
    }); 
}; 
+0

두 답변 모두 훌륭합니다. 장벽 요지가 나를 위해 속임수를했습니다. – Daniel

답변

1

for 루프 내에서 호출을 보내기 전에 개체 변수를 선언하십시오. 각 호출은 그 결과를 객체에 추가 할 수 있습니다.

그러면 모든 호출이 완료 될 때까지 기다리는 코드가 필요합니다.이 당신을 도울 수 있습니다 https://gist.github.com/464179

예 :

function getAll(callback) { 

    var results = []; 

    var b = new Barrier(2, function() { 
     // all complete callback 
     callback(); 
     }, function() { 
     // Aborted callback, not used here 
    }); 

    var list = redis.lrange(lrange('mykey', 0, -1); 
    for (var i = 0; i < list.length; i+= 1) { 
     //dispatch your call 
     call(function(foo){ 
      results.push(foo); 
      b.submit(); 
     }); 
    } 
} 

call()이 결과에 콜백을 실행하여 비동기 데이터베이스 기능을해야합니다 유의하시기 바랍니다.

3

??? 완료 될 때까지 차단하는 방법 ???

통화가 비동기 인 경우에는 통화 할 수 없습니다. getAll을 비동기 적으로 완료 할 것이라는 예상과 함께 정의한 다음 조금 다시 작성해야합니다.

레디 스 당신이 만들고있어 호출에 나는 익숙하지 해요,하지만 기본적인 패턴은 : 그 아래로 실연

function doTheBigThing(param, callbackWhenDone) { 
    asyncCallToGetList(param, function(result) { 
     var list = []; 

     asyncCallToGetNextEntry(result.thingy, receivedNextEntry); 

     function receivedNextEntry(nextResult) { 
      if (nextResult.meansWeAreDone) { 
       callback(list); 
      } 
      else { 
       list.push(nextResult.info); 
       asyncCallToGetNextEntry(result.thingy, receivedNextEntry); 
      } 
     } 
    }); 
} 

:

  1. doBigThing합니다 (getAll)를 호출한다.
  2. 우리는 목록이나 목록 핸들 등이있을 때 콜백으로 사용할 함수를 전달하여 "get the list"호출을 수행합니다.
  3. 이 콜백은 함수 receivedNextEntry을 정의하고 항목을 검색하는 데 사용되는 정보와 함께 콜백으로 전달하여 "다음 항목 얻기"함수를 호출합니다.
  4. receivedNextEntry은 가져온 항목을 저장하고 완료되면 기본 "모든 완료"콜백을 시작합니다. 그렇지 않다면 다음 요청을 발행합니다. 죄송합니다

당신에게 레디 스 별 대답을 할 수없는,하지만 난 매핑이 생각 :

  • doBigThing = getAll
  • asyncCallToGetList = redis.lrange
  • asyncCallToGetNextEntry = redis.hgetall

...하지만 매개 변수를 사용하는 경우 redis.lrangeredis.hgetall 저는 잘 모릅니다.

+0

감사합니다! 이것은 확실히 도움이됩니다! – Daniel

1

이와 같은 패턴을 자주 사용해야하는 경우 async.js library을 사용해 볼 수 있습니다. 기본적으로 의미

function getAll(callback) { 
    redis.lrange('mykey', 0, -1, function(err, reply) { 
     async.concat(reply, redis.hgetall, callback); 
    }); 
}; 

는 "모든 결과 CONCAT 다음 '응답'의 각 항목에 hgetall 호출하고 콜백에 전달"이 같은 것을 쓸 수 async.js 사용.

관련 문제