2016-10-04 3 views
1

두 개의 다른 Node.js 프로그램이 있습니다.비동기 루프 제어

하나는 Express.js 서버 (PROGRAM1)로 사용자 인터페이스와 RESTful API를 제공합니다.

다른 하나는 크롤러 (PROGRAM2)로, 항목을 계속 읽고 웹에서 다운로드하여 모든 것을 데이터베이스에 저장합니다. 그런데 Array.prototype.reduce()Promise을 사용하여 파일을 반복하고 입출력을 순서대로 처리합니다.

내가 여기에서하고자하는 한 가지 점은 PROGRAM1에서 크롤러 (PROGRAM2)의 진행 상태를 모니터링하고 제어하는 ​​것입니다.

그러나 나는 그것이 매우 복잡하다는 것을 알았습니다.

// Control the loop by this `flag`, the value can be assigned from outside 
var flag = "IDLE"; 
// The outside can read this `index`, and monitor the progress 
var current_index = -1; 
var PAGE_SIZE = 100; 
function handleBatch(index){ 
    var defer = q.defer(); 
    // Mongoose statement to find documents... 
    Book.find() 
     .skip(index*PAGE_SIZE).limit(PAGE_SIZE).then(function(books){ 
      var finished = 0; 
      for(var i=0; i<books.length; i++){ 
       var book = books[i]; 
       downloadInfo(book).then(function(bookInfo){ 
        if(flag === "STOP") 
         defer.reject(new Error("The loop should stop!")); 
        //store the info... 
        finished ++; 
        if(finished === PAGE_SIZE) 
        defer.resolve(); 
       }); 
      } 
     }); 
    return defer.promise; 
} 

var promiseHandler; 
function main(){ 
    while(true){ 
     if(flag === "IDLE") 
     continue; 
     else if(flag === "START"){ 
      var [0,1,2,3,4,5...,2500].reduce(function(lastPromise, nextIndex){ 
      promiseHandler = lastPromise.then(function(){ 
       currentIndex = nextIndex; 
      }); 
      }, q()); 
     }else if(flag === "STOP"){ 
      promiseHandler.then(null, function(err){ 
       flag = "IDLE";      
      }); 
     } 
    }  
} 

main() 단지 예 (예를 들어이. 실제로 서버, 그리고 상태 PROGRAM1의 요청에 의해 변경 될 수 있음)이다. flagSTOP으로 설정하면 handleBatch()의 루프가 변경 사항을 발견하고 Exception을 던집니다. 그러면 프로그램이 일시 중지됩니다.

그러나 나는 너무 추한 것처럼 보이고 오류를 던져서 프로세스를 제어하기 때문에이 방법을 좋아하지 않습니다. 그래서 루프를 제어하고 모니터하는 더 나은 방법을 찾고 있습니다. 어떤 생각이라도?

답변

0

node.js 'process에 대한 설명서를 찾아야합니다. 그리고 실행을 중지하는 것에 관한 질문에 대답하려면 여기 ->

process.exit (0);

팁과 마찬가지로 : 루프를 사용하여 프로그램을 제어하지 마십시오. 그것은 나쁜.

+0

사실'main()'은 단지 서버의 시뮬레이션 일뿐입니다. 내가 프로세스를 죽이고 싶지 않아 난 그냥 일시 중지하고 신호로 다시 시작할 수 ... – ppn029012

0

소리가 나면 노드 js에서 프로세스 간 통신을 구현할 수 있습니다. 이것은 노드 j를 넘어서는 광범위한 프로그래밍 주제입니다. 이를 달성하기위한 많은 패턴과 방법이 있지만 가장 좋아하는 방법 중 하나는 메시지 대기열을 사용하여 두 프로세스를 느슨하게 결합하는 것입니다.

노드 js에는 게시 - 구독 패턴을 구현하는 데 사용할 수있는 Redisnode-redis과 같은 것이 있습니다. 물론 작동시킬 많은 메시징 라이브러리가 있습니다.

경우에 따라 Express API가 "일시 중지"이벤트를 공개 할 수 있으며 크롤러가 해당 이벤트를 구독하고 조치를 취할 수 있습니다. 그러면 노드 응용 프로그램은 비동기 상태로 유지됩니다.

+0

문제는 주로 비동기 루프를 제어하는 ​​방법에 초점을, 시작/일시 중지/작업을 다시 시작보다는 프로세스 간 통신 – ppn029012

+0

이 문제는 의사 소통이 필요한 프로그램 2 개 (프로세스 간 의사 소통)로 설명합니다. 프로그램으로 제어 신호를 전달하고자한다면 콜백 함수를 사용하지 않을 것인가? while (true)는 변수의 변경에 대해 전체 CPU 폴링을 사용합니다. 즉, 자바 스크립트에서 프로그래밍하는 방식이 아닙니다. 동기식 C 코드를 작성하는 방법입니다. – saille

+0

PROGRAM2는 서버의 예입니다. 항상 runing하고 요청을 기다리는 중 ...) – ppn029012