2014-06-13 2 views
1

코딩에 익숙하지 않습니다. try ... catch가 node.js에서 작동하지 않는 이유를 이해하려고 시도합니다. 나는 예제를 만들었지 만, 예상과는 반대로 ... catch가 작동하는 것처럼 보입니다. 내 이해가 어디서 잘못 되었습니까? 도와주세요.node.js에서 try and catch 이해하기

function callback(error) { console.log(error); } 
function A() { 
    var errorForCallback; 
    var y = parseInt("hardnut"); 
    if (!y) { 
     throw new Error("boycott parsley"); 
     errorForCallback = "boycott parsley for callback"; 
    } 
    setTimeout(callback(errorForCallback),1000); 
} 

try { 
    A(); 
} 
catch (e) { 
    console.log(e.message); 
} 
// Output: boycott parsley 
// Synchronous behaviour, try...catch works 

----------- 예 ----------

function callback(error) { console.log(error); } 
function A() { 
    var errorForCallback; 
    setTimeout(function(){ 
     var y = parseInt("hardnut"); 
     if (!y) { 
      // throw new Error("boycott parsley"); 
      errorForCallback = "boycott parsley for callback"; 
     } 
     callback(errorForCallback);   
    }, 1000); 

} 
try { 
    A(); 
} 
catch (e) { 
    console.log(e.message); 
} 
// Output: boycott parsley for callback 
// Asynchronous behaviour 
// And if "throw new Error" is uncommented, 
// then node.js stops 
+0

node.js에서 작동하지 않는 이유는 무엇이라고 생각하십니까? 비동기 작업에서 발생한 예외에 대해서는 작동하지 않습니다. 이러한 종류의 오류를 잡으려면 [도메인] (http://nodejs.org/docs/latest/api/domain.html)을 사용할 수 있습니다. – mscdex

답변

3

try- 아래에 답을 읽은 후 내 이해를 반영하기 위해 짜 재 catch 방식은 동기식 코드와 완벽하게 작동하는 것입니다. Node.js에서 수행하는 모든 프로그래밍이 비동기 적이므로 작성하는 동기 코드 조각에서 try-catch 방식을 완벽하게 사용할 수 있습니다. 반면 비동기 코드는 그렇게 작동하지 않습니다. 당신은 당신이 barSync()이 완료 fooSync() 때까지 실행되는 것이 첫 번째, 세 가지를 기대하고, 당신이 x 무엇이든 값이 포함 것이라는 예상이

var x = fooSync(); 
var y = barSync(); 

같은 두 기능 실행이 있다면 예를 들어

, barSync()이 실행되기 전에 fooSync의 실행으로 반환됩니다. 또한 fooSync이 예외를 throw하면 barSync이 실행되지 않을 것으로 예상됩니다.

fooSync() 주위에서 try-catch를 사용하면 fooSync()이 실패하면 예외를 catch 할 수 있음을 보장 할 수 있습니다.

var x = fooAsync(); 
var y = barSync(); 

지금 fooAsync()이 시나리오에서 호출 될 때, 그것은 실제로 실행되지 않는 상상 :이 같은 코드를했을 경우

이제 조건이 완전히 변경합니다. 나중에 실행될 예정입니다. 마치 노드가 todo 목록을 갖고있는 것처럼 보이며 현재 모듈을 실행하는 데 너무 바빠서이 함수 호출을 찾으면이를 실행하는 대신 todo 목록의 끝에 추가합니다.

따라서 전에 barSync()이 실행될 것이라고 보장 할 수는 없습니다. 실제로는 그렇지 않습니다. 이제 fooAsync()이 실행되는 컨텍스트를 제어하지 않습니다.

따라서 fooAsync() 기능을 예약하면 즉시 barSync() 실행으로 이동합니다. 그럼 fooAsync()은 무엇을 반환 할 수 있습니까? 아직 실행되지 않았기 때문에이 시점에서는 아무 것도 없습니다. 따라서 위의 x은 아마도 정의되지 않았습니다. try-catch를이 코드 주위에두면 무의미합니다.이 코드의 컨텍스트에서 함수가 실행되지 않기 때문입니다. Node.js가 할 일 목록에 대기중인 작업이 있는지 나중에 확인할 때 나중에 실행됩니다. 이 작업 목록을 계속 확인하는 다른 루틴의 컨텍스트에서 실행되며이 실행 스레드 만 이벤트 루프라고합니다.

함수 fooAsync()이 실패하면 이벤트 루프를 실행하는이 스레드 실행 컨텍스트에서 실패하므로 그 모듈이 위의 모듈에서 가질 수있는 try-catch 문에 의해 캐치되지 않습니다 아마 실행을 끝냈습니다.

그래서 비동기 프로그래밍에서는 반환 값을 얻을 수 없으며 try-catch를 수행 할 수도 없습니다. 코드가 다른 곳에서 평가 되었기 때문에 다른 곳에서 계산 된 것이므로 그것을 불렀다.

scheduleForExecutionLaterWhenYouHaveTime(foo); 
var y = barSync(); 

그리고 비동기 프로그래밍이 마지막으로 실행될 때 코드에 무슨 일이 있었는지 결정하기 위해 다른 기술을 필요로하는 이유 : 당신이 대신 같은 것을했을 수있는 것과 같다. 일반적으로 이것은 콜백을 통해 통지됩니다. 콜백 함수는 무엇이 실패했는지 (함수가 무엇인지), 함수가 생성 한 것과 그 함수에 반응 할 수 있는지에 대한 세부 정보와 함께 호출됩니다.

+0

자세한 설명을 주셔서 감사합니다. 나는이 이해에 기초한 나의 모범을 다시 짜 냈습니다. "새 오류 던져 ..."주석을 제거하면 node.js가 중지됩니다. 그것은 시도 밖에서 오류를 던지려고하기 때문입니까? –

+0

'throw'는 함수 내의 더 이상의 코드가 그 다음에 실행되지 않는다는 점에서 'return'과 유사합니다. 여기에 던지면 콜백이 호출되지 않습니다. –

+0

아주 명확한 설명. 그러나 "Node.js에서 수행하는 모든 프로그래밍이 비동기식이 아닙니다."라고 궁금합니다. 노드가 콜백/동기화 라이브러리가 아닌 코드를 동 기적으로 실행하는시기는 언제입니까? –