>  기사  >  웹 프론트엔드  >  nodejs 최대 호출 스택 오류 문제에 대한 솔루션

nodejs 최대 호출 스택 오류 문제에 대한 솔루션

小云云
小云云원래의
2017-12-27 13:56:451653검색

이 글은 주로 nodejs의 최대 호출 스택 오류를 초과하는 문제를 소개합니다. 도움이 필요한 친구들이 참고하면 도움이 될 것입니다.

프로그램 구현 코드는 대략 다음과 같습니다


function modify(cursor) {
  cursor.hasNext(function(err,bool) {
   if(err) {
      return console.log(err); 
    } 
    if(bool) {
      cursor.next(function(err, item){
       if(err) {
       return console.log(err);
     }
     /* 此处为对数据进行update操作 */
     // 递归调用modify方法 
     return modify(cursor);
   }); 
    }else{
      console.log('finished');
    }
  })
}
var cursor = collection.find();
modify(cursor);

그런 다음 천천히 실행해 보았는데, 기분이 우울해지는 일이 일어났습니다. 커서가 500만 개에 가까워지면 프로그램이 중단되고 Uncaught RangeError: Maximum call stack size extra

메시지가 표시되고 실제로 스택이 폭발했다는 메시지가 표시됩니다. 안녕하세요, 코드를 확인하고 구멍 채우기를 시작하세요. 위에서 수정()을 재귀적으로 호출한 것을 발견했는데, 재귀 횟수가 약간 적었습니다(1,000만 개 이상의 레코드가 있는 테이블). 함수의 지속적인 재귀 호출로 인해 호출 스택이 계속 증가했기 때문일 수 있습니다. 그런 다음 점점 더 커지고 마침내 더 이상 스택이 폭발합니다. 노드에 가비지 수집을 수행할 기회를 주어야 할 것 같습니다. 가비지 수집을 수행할 기회를 갖기를 원한다면 재귀를 종료해야 합니다. 재귀 호출 스택에서 벗어나려면 시스템의 setTimeout()을 사용하십시오.

코드는 다음과 같이 수정되었습니다


function modify(cursor) { 
  cursor.hasNext(function(err,bool) {
    if(err) {
      return console.log(err); 
    }
    if(bool) {      
      cursor.next(function(err, item){
        if(err) {
          return console.log(err);
        }
        /* 此处对数据进行update操作 */
        // 递归调用modify方法 
        return setTimeout(function(){ 
              //跳出递归调用栈
              modify(cursor);
            },0);
      }); 
    }else{
      console.log('finished');
    }
  })
}
var cursor = collection.find();
modify(cursor);

실행 후 사용해 보세요. . . . 네, 작동합니다. 하지만 매번 재귀 호출 스택에서 튀어나오게 해야 하기 때문에 약간 느리게 실행됩니다. 괜찮긴 하지만 꼭 필요한 것은 아닙니다. 왜냐하면 스택은 400만 개가 넘은 후에만 폭발하기 때문입니다. 카운터를 추가하고 호출 스택이 조금 커지면 팝업합니다.


var count = 0;
function modify(cursor) { 
  count++;
  cursor.hasNext(function(err,bool) {
    if(err) {
      return console.log(err); 
    }
    if(bool) {
      cursor.next(function(err, item){
        if(err) {
         return console.log(err);
        }
        /* 此处对数据进行update操作 */
        // 递归调用modify方法 
        if(count%10000 === 0) {
          return setTimeout(function(){ 
              //跳出递归调用栈
              modify(cursor);
              },0);
        }else{
          return modify(cursor);
        }    
      }); 
    }else{
      console.log('finished');
    }
  })
}
var cursor = collection.find();
modify(cursor);

관련 권장 사항:

JavaScript 호출 스택, 꼬리 재귀 및 수동 최적화에 대한 자세한 소개

프런트 엔드 고급(6): 함수 호출 스택, 범위 체인 및 클로저 관찰

고급 프런트엔드 기본 사항(6): Chrome 개발자 도구에서 함수 호출 스택, 범위 체인 및 클로저를 관찰하세요

위 내용은 nodejs 최대 호출 스택 오류 문제에 대한 솔루션의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.