오류
오류에 대해 이야기합시다.
두 가지 유형의 오류가 있습니다.
예상되는 오류
예상되는 오류는 잘못된 일이 발생하는 상태이지만 오류가 발생할 수 있음을 알고 있으므로 처리해야합니다.
이들은 사용자 입력 또는 서버 요청과 같은 것입니다. 사용자가 실수를하거나 서버가 다운 될 수 있음을 알고 있으므로 프로그램이 다시 입력을 요청하거나 메시지를 표시하거나 기타 적절한 동작이 있는지 확인하기 위해 검사 코드를 작성합니다.
처리시 복구 가능합니다. 처리하지 않으면 예기치 않은 오류가 발생합니다.
예기치 않은 오류
예기치 않은 오류 (버그)는 코드가 잘못되어 잘못된 일이 발생한 상태입니다. 당신은 그들이 결국 일어날 것이라는 것을 알고 있지만, 정의에 따르면, 그것들은 예상치 못한 것이기 때문에 그것들을 어디서 어떻게 다루어야하는지 알 수있는 방법이 없습니다.
이들은 구문 및 논리 오류와 같은 것입니다. 코드에 오타가 있거나 매개 변수가 잘못된 함수를 호출했을 수 있습니다. 이들은 일반적으로 복구 할 수 없습니다.
try..catch
에 대해 이야기합시다 try..catch
.
JavaScript에서는 throw
일반적으로 사용되지 않습니다. 코드에서 예제를 살펴보면 거의 사이에 없으며 일반적으로 라인을 따라 구조화됩니다.
function example(param) {
if (!Array.isArray(param) {
throw new TypeError('"param" should be an array!');
}
...
}
이 때문에 try..catch
블록이 제어 흐름에 공통적 인 것은 아닙니다. 일반적으로 예상되는 오류를 피하기 위해 메소드를 호출하기 전에 몇 가지 검사를 추가하는 것이 매우 쉽습니다.
JavaScript 환경도 매우 관대하므로 예기치 않은 오류도 종종 포착되지 않습니다.
try..catch
드문 일이 아닙니다. Java 및 C #과 같은 언어에서 일반적으로 사용되는 유용한 사용 사례가 있습니다. Java와 C #은 형식화 된 catch
구문을 사용하므로 예상되는 오류와 예기치 않은 오류를 구분할 수 있습니다.
C # :
try
{
var example = DoSomething();
}
catch (ExpectedException e)
{
DoSomethingElse(e);
}
이 예에서는 다른 예기치 않은 예외가 발생하여 다른 곳에서 처리 될 수 있습니다 (예 : 프로그램을 로그하고 닫는 등).
JavaScript에서이 구문은 다음을 통해 복제 할 수 있습니다.
try {
let example = doSomething();
} catch (e) {
if (e instanceOf ExpectedError) {
DoSomethingElse(e);
} else {
throw e;
}
}
우아하지는 않습니다. 이것이 드문 이유의 일부입니다.
기능
기능에 대해 이야기합시다.
단일 책임 원칙 을 사용하는 경우 각 클래스와 기능은 단일 목적으로 사용되어야합니다.
예를 들어 authenticate()
사용자를 인증 할 수 있습니다.
이것은 다음과 같이 작성 될 수 있습니다.
const user = authenticate();
if (user == null) {
// keep doing stuff
} else {
// handle expected error
}
또는 다음과 같이 작성 될 수 있습니다.
try {
const user = authenticate();
// keep doing stuff
} catch (e) {
if (e instanceOf AuthenticationError) {
// handle expected error
} else {
throw e;
}
}
둘 다 허용됩니다.
약속
약속에 대해 이야기합시다.
약속은의 비동기 형식입니다 try..catch
. 코드를 호출 new Promise
하거나 Promise.resolve
시작합니다 try
. 전화 throw
하거나 코드로 Promise.reject
보냅니다 catch
.
Promise.resolve(value) // try
.then(doSomething) // try
.then(doSomethingElse) // try
.catch(handleError) // catch
사용자를 인증하기위한 비동기 함수가있는 경우 다음과 같이 작성할 수 있습니다.
authenticate()
.then((user) => {
if (user == null) {
// keep doing stuff
} else {
// handle expected error
}
});
또는 다음과 같이 작성 될 수 있습니다.
authenticate()
.then((user) => {
// keep doing stuff
})
.catch((e) => {
if (e instanceOf AuthenticationError) {
// handle expected error
} else {
throw e;
}
});
둘 다 허용됩니다.
중첩
중첩에 대해 이야기합시다.
try..catch
중첩 될 수 있습니다. 귀하의 authenticate()
방법은 내부적으로있을 수 있습니다 try..catch
블록 등을 :
try {
const credentials = requestCredentialsFromUser();
const user = getUserFromServer(credentials);
} catch (e) {
if (e instanceOf CredentialsError) {
// handle failure to request credentials
} else if (e instanceOf ServerError) {
// handle failure to get data from server
} else {
throw e; // no idea what happened
}
}
마찬가지로 약속은 중첩 될 수 있습니다. 비동기 authenticate()
메소드는 내부적으로 약속을 사용할 수 있습니다.
requestCredentialsFromUser()
.then(getUserFromServer)
.catch((e) => {
if (e instanceOf CredentialsError) {
// handle failure to request credentials
} else if (e instanceOf ServerError) {
// handle failure to get data from server
} else {
throw e; // no idea what happened
}
});
그래서 대답은 무엇입니까?
좋아, 나는 실제로 질문에 대답 할 때가되었다고 생각한다.
인증 실패가 약속을 거부하는 것으로 간주됩니까?
내가 줄 수있는 가장 간단한 대답 throw
은 동기 코드 인 경우 예외를 원할 경우 약속을 거부해야한다는 것 입니다.
명세서 if
에서 몇 가지 점검을 통해 제어 흐름이 더 단순 then
하다면 약속을 거부 할 필요가 없습니다.
약속을 거부하고 오류 처리 코드에서 오류 유형을 확인하여 제어 흐름이 더 간단한 경우 대신 처리하십시오.
reject
하고 false를 반환하지,하지만 당신은을로 값을 예상하는 경우Bool
에, 당신은 있었다 성공과 상관없이 값의 BOOL으로 해결해야한다. 약속은 값에 대한 일종의 프록시입니다. 반환 된 값을 저장하므로 값을 얻을 수없는 경우에만 반환됩니다reject
. 그렇지 않으면해야합니다resolve
.