2013-07-12 2 views
4

mongoose으로 시작하는 경우 컬렉션에서 일괄 처리 작업을 수행해야하는 경우가 있습니다. 그러나 일반적으로 노드 j에는 동시성이 코딩 된 까닭 인 콜백이 포함됩니다. 그래서 기본적으로노드에서 비동기 및 재귀

//given a collection C 
var i = 0; 
var doRecursive = function(i){ 
    if(i<C.length){ 
     C[i].callAsync(err,result){ 
     i=+1; 
     return doRecursive(i); 
     } 
    }else{ 
     return done(); 
    } 
} 
doRecursive(i); 

지금 내가 노드와 stackover 흐름을 얻기 전에 최대 스택 무엇인지 기억 해달라고,하지만 난 10 개 000 요소로 생각, 그것은 늘 않습니다. 처리 할 수있는 다른 방법이 있는지 궁금합니다. 그렇다면 무엇입니까? 감사가

+1

음에

doRecursive(C, ++i); 

을 변경하여 장기 실행 작업을 연기 할 수 있습니다 호출 스택. 그러나 다른 스택으로 나눠서, 쓸모없는'return'을 렌더링합니다. –

+1

[async] (https://github.com/caolan/async)를보세요 –

답변

5

목표가 비동기 적으로 컬렉션을 반복하는 것이면 많은 제어 흐름 라이브러리를 사용할 수 있습니다.

좋은 예는 async하고 reduce function입니다 :

async.reduce(C, 0, function (memo, item, callback) { 
    item.callAsync(function (err, result) { 
     if (err) { 
      callback(err); 
     } else { 
      callback(null, memo + result); 
     } 
    }); 
}, function (err, result) { 
    // ... 
}); 

참고 : 그것은 당신이 doRecursion에서 얻을 싶어 어떤 값을 완전히 명확하지 않다, 그래서 이것은 단지 예를 들어 추가를 사용합니다.

+0

나는 비동기를 알고 있습니다. async에는 재귀를 일반화 할 수있는 방법이 있으므로 재귀를 "더 예쁜"방식으로 작성할 수 있습니까? 사람들은 재귀 호출과 비동기 호출에 대한 stackoverflow 문제가 없어야한다고 말하고 있습니다. 확실히 테스트해야합니다. 편집 : 당신이 재미있는 Async.reduce를 사용하여, 그 하나에 대해 몰랐 참조하십시오. – mpm

1

난 당신이 깊은 개체로 드릴하지 않을 때문에, 당신은 단순히 자기 반복 처리 대신에 진정한 재귀를 수 있다고 생각 : 라벨로

function doRecursive (C, i){ 
    i=i||0; 
    if(i<C.length){ 
     C[i].callAsync(err, function(result){ 
      doRecursive(C, ++i); 
     }); 
    }else{ 
     done(); 
    } 
}; 

doRecursive(C); 

이 코드 기능의 경우 높이 스택을 만들지 않습니다. 더 빨리 실행되고 잠재적으로 다른 컬렉션에서 재사용 할 수 있도록 C가 현지화되었습니다. 패턴은 비동기 함수는 콜백이 다른에있을 것 같은 스택 오버 플로우에 도움이 될 것입니다 쉽게 단지

setTimeout(doRecursive.bind(this, C, ++i), 50); 
관련 문제