>  기사  >  웹 프론트엔드  >  nodejs에서 최대 호출 스택 초과 오류를 해결하는 방법

nodejs에서 최대 호출 스택 초과 오류를 해결하는 방법

亚连
亚连원래의
2018-06-15 11:27:141815검색

이 글은 nodejs가 최대 호출 스택 오류를 초과하는 문제를 주로 소개하고 있으니 필요하신 분들은 참고하시면 됩니다

오늘 아침 사장님께서 이전 프로젝트의 데이터를 변경해야 하고, mongodb의 모든 기록을 변경해야 한다고 하셨습니다. 업데이트해야 합니다. 스크립트를 작성하고 실행하면 됩니다.

이후 조용히 컴퓨터로 돌아왔고, 다시 힘든 하루가 시작되었습니다. 이 테이블의 데이터 용량이 좀 크기 때문에 레코드 수는 1,000만 개 이상이어야 합니다. 따라서 이동하고 수정하려면 mongodb의 커서를 사용하는 것이 좋습니다.

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

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에서 Generator를 사용하는 방법

노드에서 아바타를 변경하는 방법

404 반응 라우터에서 페이지를 새로 고칠 때 문제가 발생합니다

Vue 이벤트 수정 세부 정보 부적 포획 사용

위 내용은 nodejs에서 최대 호출 스택 초과 오류를 해결하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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