자바 스크립트에서 try-catch ... 좋은 습관이 아닙니까?


69

javascript 에는 try-catch 블록이 제공됩니다 . Java 또는 다른 언어에서는 오류 처리가 필수적이지만 Javascript에서 더 큰 오류를 사용하는 사람은 없습니다. 좋은 습관입니까, 아니면 자바 스크립트에서 필요하지 않습니까?


2
While in java or *any other language* it is mandatory to have error handling...-아니에요 Java는 가능하지만 try-catch를 주장하지 않는 많은 언어가 있습니다 (예 : C #).
Jim G.

비동기 환경에서는 사용할 수 없기 때문입니다. 예를 들어 무언가를 무언가로 변환하는 등 낮은 추상화 레벨로 동기화 코드를 사용하여 자주 사용합니다.
inf3rno

클라이언트 측 코드보다 서버 측 코드에서 더 많은 try-catch가 표시됩니다. 당신이 가장 선호하는 cliend-side 코드의 대부분은 중요하지 않습니다. 파이프 아래로 KB를 최소화하는 것이 대부분의 응용 프로그램 및 브라우저 쪽 환경에서 모든 오류를 복구하는 것보다 중요합니다.
svidgen

어쩌면 우리가 노드로 작성된 웹 스크레이퍼를 가지고 시도하고 어쩌면 Emother (monads)를 사용하여 시도를 피하는 다른 방법이 있습니다. 우리는 그것을 사용하여 모든 시도 캐치를 제거 할 수있었습니다.
user93

답변:


66

throw응용 프로그램에서 오류 조건을 전달하는 방법으로 오류를 피해야 합니다.

throw문은 "이런 일이없고, 충돌 및 굽기 안 들어. 어떤 방식으로 우아하게 복구 안 함"을 사용한다

try catch 그러나 호스트 객체 또는 ECMAScript가 오류를 발생시킬 수있는 상황에서 사용됩니다.

예:

var json
try {
    json = JSON.parse(input)
} catch (e) {
    // invalid json input, set to null
    json = null
}

node.js 커뮤니티의 권장 사항은 콜백에서 오류를 전달하는 것입니다 (오류는 비동기 작업에만 발생하므로).

fs.readFile(uri, function (err, fileData) {
    if (err) {
        // handle
        // A. give the error to someone else
        return callback(err)
        // B. recover logic
        return recoverElegantly(err)
        // C. Crash and burn
        throw err
    }
    // success case, handle nicely
})

try / catch와 같은 다른 문제도 실제로 비싸며 추악하고 비동기 작업에서는 작동하지 않습니다.

따라서 동기식 작업은 오류를 발생시키지 않아야하며 비동기식 작업에서는 작동하지 않으므로 호스트 객체 또는 ECMAScript에서 발생한 오류를 제외하고 아무도 try catch를 사용하지 않습니다.


2
아무도 try catch를 사용 하지 않는다고 말하지 않을 것 입니다. 대부분의 경우 작업에 잘못된 도구 일뿐입니다. 정말 예외적 인 상황이 발생하면을 던질 가치가 Error있지만 그 사이는 거의 없습니다.
zzzzBov

7
@zzzzBov 사례 C, 충돌 및 굽기에 대한 오류를 던지는 데 아무런 문제가 없습니다. 난 단지 당신이 오류를 잡아 복구해야한다고 생각하지 않습니다. 예를 들어 document.getElementById요소가 존재하지 않을 때는 던지지 않고 그냥 반환합니다 null. 거의 모든 경우에 동일하게 적용 가능
Raynos

4
@Raynos는 동기화 기능에서 완전히 허용되며 해당 사용 사례에서 의미가 있습니다. 콜백에 오류를 반환하는 것은 던지는 오류가 동기화되므로 비동기입니다.
sbartell

@Raynos는 클라이언트 측 (비 노드 환경)에서 흐름 제어를 위해 오류 / 예외를 사용하지 않는 것에 대한 좋은 조언이 있습니까? 나는이 발견했습니다 에 StackOverflow에 게시물을 하지만, 주로 자바에 맞 있어요
blong

@ b.long 간단합니다. 절대 오류를 던지지 마십시오. 문제 해결됨.
Raynos

32

Javascript의 try / catch는 Javascript의 비동기 특성으로 인해 다른 언어 에서처럼 방탄하지 않습니다. 이 스 니펫을 고려하십시오.

try {
    setTimeout(function() {
        do_something_that_throws();
    }, 1000);
}
catch (e) {
    alert("You won't see this!");
}

문제는 제어 흐름 이 실행 try되기 전에 블록을 떠나 do_something_that_throws()므로 콜백 내부에서 발생하는 오류는 포착되지 않는다는 것입니다.

따라서 try / catch는 기본적으로 대부분의 경우 부적절하며 코드가 비동기 적으로 실행되는지 여부가 항상 명확하지는 않습니다. 다행스럽게도 고유 한 단일 스레드 비동기 콜백 관용구와 실제 클로저에 대한 지원을 갖춘 Javascript는 연속 전달 스타일 오류 처리와 같은 우아한 대안을 제공합니다. 함수로서 오류에 대한 올바른 응답을 전달하십시오. 예 :

setTimeout(function () {
    do_something_that_calls_err(function(err) {
        alert("Something went wrong, namely this: " + err);
    }),
    1000);

5
다른 언어로도 방탄이 아닙니다. 해당 코드를 비동기 콜백을 지원하는 모든 언어로 포팅하면 실패합니다.
Raynos

2
@Raynos : 네 말이 맞아. 그러나 다른 언어 (또는 지원 문화)는 Javascript와 같이 비동기 콜백 관용구에 이것을 많이 사지 않으며 대부분의 다른 환경의 다중 스레드 특성으로 인해 try / catch의 단점이 더 분명합니다. 다른 많은 경고에 둘러싸여 사람들은 멀티 스레드 / 비동기 콜백 상황에서 자연스럽게 조심스럽게 밟고 잠재적 인 함정을 더 잘 알고 있습니다.
tdammers

이것이 실제로 JavaScript의 "비동기 적 특성"때문입니까? 내가 볼 수있는 한, Try / Catch는 이론적으로 식별자가 어휘 적으로 닫히는 방식과 같이 어휘 적으로 작동하도록 만들 수 있습니다. JavaScript에서는 그런 식으로 작동하지 않습니다.
Brian Gordon

2
Node.js를에서> = 0.8 비동기 적으로 잡기 / 시도 할 수 있습니다 주목할 가치가있다, 내 질문 참조하십시오 stackoverflow.com/questions/14301839/...
벤자민 Gruenbaum

동기식 try-catch의 유일한 대안은 비동기 연속 전달 스타일입니까?
CMCDragonkai

23

이러한 답변 중 상당수는 약간 오래되었으며 새로운 ES7 기능 async과 를 고려하지 않았습니다 await.

async/ await를 사용 하면 원하는대로 비동기 제어 흐름을 얻을 수 있습니다.

async function email(address) {
  try {
    // Do something asynchronous that may throw...
    await sendEmail({ to: address, from: 'noreply@domain.com`, subject: 'Hello' })
  } catch(err) {
    if (err instanceof SomeCustomError) {
      elegantlyHandleError(err)
    } else {
      throw err
    } 
  }
})

async/ awaithere 에 대해 자세히 알아보십시오 . babel을 사용 async하거나 await지금 사용할 수 있습니다 .


그러나 이것은 동기 코드와 유사합니다
Atul Agrawal

@AtulAgrawal 예, 그게 요점입니다. 비동기 / 대기 (Async / await)를 사용하면 비동기 스타일로 동기 코드를 작성할 수 있으므로 "콜백 지옥 (callback hell)"과 많은 약속들을 함께 묶을 수 있습니다. 제 생각에는 비동기 코드를 작성하는 매우 즐거운 방법입니다.
Dana Woodman

따라서 비동기 코드를 동기 코드로 만드는 경우 Javascript를 사용하면 어떤 이점이 있습니까? 대부분의 사람들은 비동기 특성으로 인해 자바 스크립트를 사용하기 때문에
Atul Agrawal

2
@AtulAgrawal은 위의 코드가 여전히 비동기로 실행되므로 스레드가 모두 해제되므로 언어의 비동기 특성을 즐기고 더 프로그래머에게 친숙한 코딩 스타일의 이점을 제거 할 수 있습니다. 문제가없는 것은 아니지만 ...
ZenMaster

15

Javascript의 try-catch는이를 구현하는 다른 언어와 마찬가지로 유효하고 유용합니다. 다른 언어 에서처럼 자바 스크립트에서 많이 사용되지 않는 주된 이유가 있습니다. Javascript가 추악한 스크립팅 언어로 보이는 것과 동일한 이유는 사람들이 Javascript 프로그래머가 실제 프로그래머가 아니라고 생각하는 것과 같은 이유입니다.

  • 자바 스크립트는 믿을 수 없을 정도로 널리 보급 된 언어입니다

많은 사람들이 브라우저에 의해 지원되는 유일한 언어 덕분에 자바 스크립트에 노출된다는 사실은 전문가가 아닌 코드가 많이 있다는 것을 의미합니다. 물론 몇 가지 사소한 이유가 있습니다.

  • 자바 스크립트의 일부는 비동기이므로 사용할 수 없습니다 catch(비동기식)
  • try-catch가 어떻게 큰 성능 저하를 가져 왔는지에 대해 너무 많은 이야기가있었습니다. 그것은이 성능 저하의 조금 있지만, 대부분의 코드, 그것은 잘 가치가있다.
  • 자바 스크립트는 불행히도 오류를 자동으로 무시하는 방식으로 구현되었습니다 (예 : 문자열을 숫자로 자동 변경)

어쨌든 try-catch를 사용해야 하지만 프로그래밍의 다른 모든 것과 마찬가지로 올바르게 사용하는 방법을 배워야합니다 .


3
그리고 왜 당신은 downvote를 다운 적이 있습니까?
user250878

동의했다. 나는 받아 들인 대답이 일반적으로 사실이라고 생각하지만 기본 객체를 처리 할 때를 제외하고 try-catch를 사용하고 심지어 던질 이유가 있습니다. 콜백에 전달되지 않고 오류가 발생하면 추가 실행이 중지되고 스택을 처리 할 수있는 것보다 스택을 첫 번째 블록으로 점프합니다. 이는 특히 강력한 중첩이 필요한 경우 동기 작업에 매우 적합하고 완벽하게 이해됩니다. 예외가 "나쁜"(명백한 이유가 아닌 다른 것)을 제안하는 것은 미친 것 같습니다. 실제로는 독특한 "파워"를 가진 매우 유용한 도구입니다.
세미콜론

2
jQuery와 같은 소스 코드를 읽는 데 시간이 걸린 적이 있습니까? 허용 된 답변에 언급 된 시나리오를 제외하고는 오류를 발생시키는 네이티브 / 호스트 객체를 특징으로 감지하고 사용하는 것을 제외하고는 그 어떤 시도도 거의 없습니다. jQuery와 같이 try-catch를 많이 사용하지 않는 코드를 호출하는 것은 '비전문가'처럼 보이지 않습니다. 솔직히 말해서, 나는 try-catch와 같은 언어 기능을 과도하게 사용하는 경향이있는 Java에서 온 새로운 Javascript 프로그래머라고 생각합니다.
Stijn de Witt

6

try..catchJavaScript에서 드물게 발생 하는 많은 이유 는 언어에 오류에 대한 내성이 매우 높기 때문 이라고 생각합니다 . 대부분의 상황은 코드 확인, 양호한 기본값 및 비동기 이벤트를 사용하여 처리 할 수 ​​있습니다. 경우에 따라 단순히 패턴을 사용하면 문제를 방지 할 수 있습니다.

function Foo() {
    //this may or may not be called as a constructor!!
    //could accidentally overwrite properties on window
}

function Bar() {
    if (!(this instanceof Bar)) {
        return new Bar();
    }
    //this will only work on Bar objects, and wont impact window
}

예외가 발생하는 다른 언어의 주요 문제 중 일부는 JS에 존재하지 않습니다. 대부분의 경우 유형 캐스팅이 필요하지 않습니다. 대신 선호되는 방법은 일반적으로 기능 검사 (특정 인터페이스 적용)입니다.

function doFoo(arg) {
    if (arg.foo) {
        arg.foo();
    } else {
        Bar.prototype.foo.call(arg);
    }
}

언어 에 async/ await를 추가하면 try..catch점점 더 널리 퍼지고 있습니다. 의 비동기 형식으로 약속하지만 다음과 같이 try..catch기대해야합니다.

doSomething().then(
  doSomethingWithResult,
  doSomethingWithError
)

대신 다음과 같이 작성하십시오.

try {
  const result = await doSomething()
  doSomethingWithResult(result)
} catch (e) {
  doSomethingWithError(e)
}

3

try / catch가 Javascript에서 많이 사용되지 않는 또 다른 이유는 첫 번째 버전의 Javascript에서 구문을 사용할 수 없기 때문에 나중에 추가 된 것입니다.

결과적으로 일부 구형 브라우저는이를 지원하지 않습니다. (실제로, 일부 구형 브라우저에서는 파서 / 구문 오류가 발생할 수 있습니다. 이는 대부분의 다른 유형의 오류보다 "방어 적으로 프로그래밍"하기가 더 어렵습니다.

더 중요한 것은 처음에는 사용할 수 없었기 때문에 처음 릴리스 된 Javascript 내장 함수 (많은 언어에서 "라이브러리"함수라고 함)는이 함수를 사용하지 않습니다. ( "throw"하지 않고 문제가 발생했을 때 "null"을 반환하는 경우 someobject.somefunction ()에서 오류를 "잡아내는"작업은 매우 효과적이지 않습니다.


또 다른 가능한 이유는 try / catch 메커니즘이 처음에는 필요하지 않은 것 같습니다 (그리고 여전히 유용한 것은 아닙니다). 통화가 일상적으로 여러 수준으로 중첩 된 경우에만 필요합니다. 일종의 ERRNO를 반환하면 직접 호출에 제대로 작동합니다 (사용 가능한 경우 항상 유용하게 사용 하기는하지만 대부분의 언어에서 가장 좋은 방법은 깊게 중첩 된 호출이 아닌 모든 곳 에서 사용하는 것입니다). Javascript 로직은 원래 작고 단순해야했지만 (결국 웹 페이지 :-에 대한 보조 일 뿐임) 함수 호출은 깊이 중첩되지 않았으므로 try / catch 메커니즘이 필요하지 않은 것 같습니다.


3
아니요 아니요 아니요, 절대 그렇지 않습니다. 오래된 엔진은 더 이상 오랫동안 중요하지 않으며 일반적으로 자바 스크립트 커뮤니티는 정당화되면 오래된 것을 빨리 떨어 뜨립니다. 나는 현재 대다수의 자바 스크립트 개발자들이 IE6 이후라고 생각한다.
Camilo Martin

0

Javascript 클라이언트 측 코드에서 예외를 throw하면 페이지를 디버깅하기가 더 어려워서 많이 사용되지 않는다고 생각합니다.

오히려 예외를 던지는 것보다, 내가 일반적으로 알 경고 상자를 표시하는 것을 선호 (예 alert("Error, invalid...");)

이상하게 들릴지 모르지만 고객이 작성한 페이지를 사용하고 있고 기술에 정통한 리더 가 아니라면 고객이 말할 수있는 방법이 없다면 고객이 Javascript 오류가 발생합니다. 당신은 문제가 무엇입니까.

"X 페이지가 작동하지 않습니다!" 라는 말만으로 전화를 걸어 문제가 발생한 부분과 코드의 위치를 ​​찾는 것은 전적으로 귀하의 책임입니다.

대신 경고 상자를 사용하면 전화를 걸거나 "X 페이지의 A 단추를 클릭하면 ..."라고 표시된 상자가 표시됩니다. "라고 믿으면 훨씬 쉽게 찾을 수 있습니다. 버그.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.