2014-09-02 4 views
0

콜백은 비동기식입니다. 따라서 콜백에서 오랜 계산을 실행하면 주 스레드에 영향을 미치지 않습니다. 예를 들어NodeJs/expressjs : 콜백에서 긴 코드 실행

는 :

function compute(req,res){ // this is called in an expressjs route. 
    db.collection.find({'key':aString}).toArray(function(err, items) { 
     for(var i=0;i<items.length;i++){  // items length may be in thousands. 
      // Heavy/lengthy computation here, Which may take 5 seconds. 
     } 
     res.send("Done"); 
    }); 
} 

그래서, 데이터베이스에 대한 호출이 ascnchronous입니다. 콜백 내부의 for 루프는 메인 스레드를 차단하지 않을 것인가?

차단하는 경우 어떻게 비동기식으로 수행 할 수 있습니까?

+1

콜백 *은 기본 스레드에 있습니다. node.js *에는 하나의 스레드 * 만 있습니다. 다른 프로세스에 위임하지 않고 node.js에서 2 밀리 초 이상을 소비 할 때마다 기분이 나빠질 것입니다. :) – Amadan

+0

그래, 나는 그렇게 느꼈다. 그러나 아무것도 그것에 관해 할 수 없냐? 실제로 나는 5 초를 말함으로써 과장했다. 그러나 때로는 일부 처리가 필요합니다. – codin

답변

1

대부분 node.js는 단일 스레드에서 실행됩니다. 그러나 node.js는 별도의 스레드에서 처리하는 저수준 작업 (파일 읽기, 네트워크 요청 등)을 실행하는 호출을 할 수 있습니다. 따라서 데이터베이스 호출은 개별 스레드에서 발생합니다. 그러나 데이터베이스 호출이 돌아 오면 주 스레드로 돌아가고 코드는 주 스레드에서 실행됩니다 (차단).

이 문제를 해결하는 방법은 새 스레드를 위로 돌리는 것입니다. 이것을 수행하려면 cluster을 사용할 수 있습니다. 참조 : 데이터베이스 호출 완료, 그것은 fork()를 호출하고 your-calculations.js을 실행과에 이벤트를 전송하는 새로운 스레드를 회전 할 때

http://nodejs.org/api/cluster.html

  • 메인 프로그램이 데이터베이스 호출
  • 를 만들 것입니다 임의의 입력 데이터
  • your-calculations.js
  • 이벤트를 수신하고 이벤트를 처리 할 때 필요한 처리를 수행 할
  • your-calculations.js 다음 이벤트를 보낼 메인 스레드는 출력 데이터를 필요로하는 경우 다시이 처리 완료 메인 스레드에
  • (이 모든 출력 데이터를 다시 보낼 수 있습니다), 그것은 your-calculations.js
+0

솔루션처럼 보입니다. 먼저 읽어야합니다. 고마워요 – codin

1

을 방출하는 이벤트를 수신 할 수 있습니다 '당신이 할 수있는 경우 스레드를 사용하고 싶지 않으면 setImmediates를 사용하여 긴 계산을 나눌 수 있습니다. 예 : 그들이 evedntually 또 다른 거대한 계산을 트리거 경우, 다른 콜백 등 물론 처리, 노드가 다른 요청을 처리 할 시간이됩니다 모든 100 개 계산 사이에서

function compute(startIndex, max, array, partialResult, callback) { 
    var done = false; 
    var err = null; 
    var stop = startIndex+100; // or some reasonable amount of calcs... 
    if (stop >= max) { 
     stop = max; 
     done = true; 
    } 

    // do calc from startIndex to stop, using partialResult as input 
    if (done) 
     callback(err, result); 
    else 
     process.setImmediate (go look this part up or I'll edit tomorrow)... 
     But the idea is you call youself again with start += 100. 
} 

(내 태블릿에 신속하게 작성하는 것은 너무 부주의있을 수 있습니다) 일이 중단 될 것입니다.

+0

물론, 제가 프로세스를 확인합니다. 세트 즉시. 감사. – codin