2017-01-06 3 views
1

저는 Node js 프로그래밍에 초보자이므로 핵심 개념과 프랙티스를 매우 적절하게 이해하고자합니다. AFAIK 노드 js는 모든 디스크 및 기타 I/O 작업이 비동기식으로 실행되도록 비 차단 I/O를 가지고 있으며 JS는 Event Loop을 사용하여 리소스 및 실행 경로를 관리하는 단일 스레드에서 실행됩니다. 많은 곳에서 제안 된대로 개발자는 콜백 패턴을 사용하여 사용자 정의 함수/메소드를 작성하는 것이 좋습니다.노드 JS에서의 이벤트 루프 블로킹 및 비동기 프로그래밍

function processData(inputData, cb){ 
    // do some computation and other stuff 

    if (err) { 
    cb(err, null); 
    }else{ 
    cb(null, result); 
    } 
} 
callback = function(err, result){ 

// check error and handle 

// if not error then grab result and do some stuff 
} 

processData(someData, callback) 
// checking whether execution is async or not 
console.log('control reached at the end of block'); 

이 코드를 실행하면 모든 것이 콘솔 메시지 출력과 동시에 동 기적으로 실행됩니다. 내가 믿었던 것은 콘솔 메시지가 먼저 콜백 함수를 호출하는 processData 함수 코드의 실행 다음에 인쇄된다는 것입니다. 그리고 이런 식으로 발생하면 이벤트 루프는 차단 해제되고 최종 응답이 '콜백'기능으로 준비 될 때 요청에 대한 응답 만 실행합니다.

제 질문은 : - 노드의 성격에 따라 실행 순서가 올 바르습니까? 아니면 제가 잘못한 일을하고 있습니까? 아니면 중요한 개념을 놓치고 있습니까?

어떤 도움을 주셔서 감사합니다.

답변

1

자바 스크립트 (다른 ​​언어와 마찬가지로)가 순차적으로 실행됩니다. 당신이

var x = 1; 
x *= 2; 
x += 1; 

을 작성하는 경우에는 결과가 3하지 4이 될 것으로 기대합니다. 그것은 꽤 나쁠 것입니다. 기능도 마찬가지입니다. 쓸 때

foo(); 
bar(); 

매우 비슷한 순서로 실행되기를 기대합니다.

var foo = function() {}; 
var bar = function(clb) { 
    clb(); 
    foo(); 
}; 
var callback = function() { 
}; 
bar(callback); 

예상 실행 순서가 bar -> callback -> foo입니다 : 중첩 기능이 때 변경되지 않습니다.

그래서 사람들이 인터넷에서하는 가장 큰 피해는 비동기 프로그래밍과 콜백 패턴 사이에 등호를 삽입한다는 것입니다. 이것은 잘못된입니다. 콜백 패턴을 사용하는 많은 동기 함수가 있습니다. Array.prototype.forEach().

실제로 일어나는 현상은 NodeJS에이 이벤트 루프가 있다는 것입니다. 여러 가지 특수 기능을 호출하여 일정을 계획하고 나중에 실행할 수 있습니다. setTimeout, setInterval, process.nextTick으로 이름을 지정하십시오. 모든 I/O는 이벤트 루프에서 수행 할 일정을 예약합니다. 당신이

var foo = function() {}; 
var bar = function(clb) { 
    procress.nextTick(clb); // <-- async here 
    foo(); 
}; 
var callback = function() { 
}; 
bar(callback); 

을한다면 지금 예상 실행 순서는 bar -> (schedule callback) -> foo 다음 callback 어떤 시점에서 발사됩니다이 (즉, 다른 모든 대기중인 작업이 처리 될 때)입니다.

그것이 작동하는 방식은 거의 같습니다.

+0

확인. 따라서 setTimeOut 또는 다른 지연된/지연된 타이밍 함수 내에 일반적인 코드 (개발자가 작성한 코드)를 래핑하면 컨트롤이 즉시 거기에서 다음 실행 행으로 돌아가므로이 메서드는 이벤트 루프가 다음 요청에 참여할 수있는 공간을 만듭니다 열. 따라서 노드 js의 경우 대부분의 개발자 코드가 내부에 래핑되거나 비 차단 코드 실행을 허용하기 위해 이러한 특수 함수를 사용해야합니까? – iThirst

+0

@iThirst 비 차단 코드를 허용하려면 ** 특수 기능을 사용해야합니다 **. 그러나 많은 라이브러리 (예 : 데이터베이스 드라이버)가 사용자를 위해이를 수행합니다.이벤트 루프는 C 레벨에서 액세스 할 수도 있습니다 (C 플러그인을 작성하는 경우). 또한 비 차단 코드가 필요한지 여부는 컨텍스트에 따라 다릅니다. 대부분의 경우 (예 : db와 같은 외부 리소스를 사용하지 않는 경우) 사용하지 않으면 문제가 없습니다. – freakish

+0

확인. 따라서 I/O를 포함하지 않는 코드는 이벤트 루프 차단에 눈에 띄게 영향을 미치지 않습니다. 또한 DB 상호 작용을 위해 mongoose 라이브러리를 사용하고 위와 유사한 코드를 사용하여 비동기 실행을 평가했습니다. 그러나이 경우에도 콘솔이 마침내 인쇄되고 몽구스 코드가 먼저 실행됩니다. mongoose는 콜백 콜을 제공 한 후에도 비동기식으로 비동기식으로 실행합니까? – iThirst

관련 문제