JS 튜토리얼 기본 6부

밍글·2023년 5월 9일
0

JS튜토리얼정리

목록 보기
6/10
post-thumbnail

이번에는 Error Handling과 Promise와 async,await에 대해서 알아보도록 하겠다. 일부만 정리하였기 때문에 자세하게 알고 싶다면 1부에 적었던 참고사이트를 활용하면 될 것이다🙇🏼


Error Handling

아무리 코드를 잘 짠다고 해도 에러를 발생시킬 수 있다. 원인은 실수, 입력 오류, 잘못된 서버 응답 등 다양하기 때문에 에러가 발생하면 스크립트는 ‘죽고’(즉시 중단되고), 콘솔에 에러가 출력된다. 이 때 Error Handling을 이용하여 스크립트가 죽는 걸 방지하고, 에러를 ‘잡아서(catch)’ 더 합당한 무언가를 할 수 있게 한다.

try...catch

//기본 문법
try {

  // 코드...
  // 1. 먼저 try에 해당하는 코드가 실행된다
  // 2. 에러가 없다면, try 안의 마지막 줄까지 실행되고, catch 블록은 스킵한다.

} catch (err) {

  // 에러 핸들링
  // 3. 에러가 있다면, try문의 코드는 중단되고 catch(err) 블록으로 제어 흐름이 넘어간다. 
  //변수 err에는 무슨 일이 일어났는지에 대한 설명이 담긴 에러 객체를 포함한다.

}

throw 연산자

에러를 직접 만들 수 있다. 이론상으론, throw 인수에 모든 것을 넘길 수 있지만, 대개 내장 Error 클래스를 상속받은 에러 객체를 인수에 넘긴다.

//JSON.parse의 에러 종류
try {
  JSON.parse("{ 잘못된 형식의 json o_O }");
} catch(e) {
  alert(e.name); // SyntaxError
  alert(e.message); // JSON Parse error: Unrecognized token '잘'
}

//JSON 에러 throw로 처리하는 예시
let json = '{ "age": 30 }'; // name이 없는 불완전한 데이터

try {

  let user = JSON.parse(json); // <-- 에러 없음

  if (!user.name) {
    //JSON Parse의 error 종류는 SyntaxError였기 때문
    throw new SyntaxError("불완전한 데이터: 이름 없음");
  }

  alert( user.name );

} catch(e) {
  alert( "JSON Error: " + e.message ); // JSON Error: 불완전한 데이터: 이름 없음
}

⭐️try..catch는 오직 런타임 에러에만 동작한다
⭐️try..catch는 동기적으로 동작한다.
⭐️ 에러 객체가 필요 없으면 catch(err) { 대신 catch {를 쓸 수 있다.
⭐️try..catch는 finally를 이용하여 확장할 수 있다

try {
   ... 코드를 실행 ...
} catch(e) {
   ... 에러 핸들링 ...
} finally {
   ... 항상 실행 ...
}
   // ‼️try..catch..finally 안의 변수는 지역 변수‼️
   // ‼️finally 절은 try..catch 절을 빠져나가는 어떤 경우에도 실행‼️
   /* finally 안의 코드가 실행되고 난 후,
   try값이 바깥 코드가 반환됨
   (return이 try블록 안에 있는 경우)*/

에러 다시 던지기

1️⃣ catch가 모든 에러를 받는다.
2️⃣ catch(err) {...} 블록 안에서 에러 객체 err를 분석한다. 이 때 에러 타입을 instanceof 명령어로 체크한다.
3️⃣ 에러 처리 방법을 알지 못하면 throw err를 해서 에러를 다시 던진다.

//에러를 다시 던져 예상치 못한 에러를 처리하기
function readData() {
let json = '{ "age": 30 }'; // 불완전한 데이터
try {

  let user = JSON.parse(json);
  

//   if (!user.name) {
//     throw new SyntaxError("불완전한 데이터: 이름 없음");
//   }

  blabla(); // 예상치 못한 에러

  alert( user.name );

} catch(e) {

  if (e instanceof SyntaxError) {
    alert( "JSON Error: " + e.message );
  } else {
    throw e; // 에러 다시 던지기 (*)
  }

}
}

try {
  readData();
} catch (e) {
  alert( "External catch got: " + e ); // 에러를 잡음
}

Promise와 async,await

동기와 비동기

비동기는 응답과 요청이 동시에 일어나지 않는 걸 의미한다(즉, 요청을 한번에 받고 응답에 대한 결과를 주기 때문에 한번에 여러 작업을 할 수 있다) 동기는 그 반대의 의미를 지닌다. 그림으로 보면 다음과 같이 나타낼 수 있다.
그림 참고자료 : https://liarchild.tistory.com/35

Promise

비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타낸다.
Promise의 상태는 3가지로 분류할 수 있는데 사실상 이행과 거부라고 나타날 수 있다. ➡️ 그 이유는 대기 상태를 지나야 이행 혹은 거부 두 상태 중 하나를 반환하게 되기 때문!

1️⃣ 대기(pending) : 비동기 작업 진행중인 상태, 초기 상태
2️⃣ 이행(fulfilled) : 연산이 성공적으로 완료됨
3️⃣ 거부(rejected) : 연산이 실패함

Promise의 결과에 따라 .then 또는 .catch로 수행할 수 있다.

.then : resolve일 때 수행되며, 다음과 같이 두 함수를 활용할 때는 꼭 return을 해야한다. 그 이유는 return이 .then에 해당하는 Promise를 담당하기 때문이다.
.catch : reject일 때 어떤 곳에 error가 나도 한꺼번에 처리가 가능하다.

//.then .catch 사용 예시 
.then(postId => {
   console.log('Post:', postId)
   return getComments(postId)
//생략
.catch(message => console.log(message));

async, await

왜 사용할까?

  1. 어떤 코드가 먼저 실행되었는지 순서를 알기 어려워진다.
    → 에러 원인 불명확
    → 디버깅 어려움
    → 코드 예측성 떨어짐
  2. 코드 중첩
    → 가독성 떨어짐

사용할 시 이점

function 앞에 async 키워드를 추가 할 때 이점
1️⃣ 함수는 언제나 Promise를 반환한다.
2️⃣ 함수 안에서 await를 사용할 수 있다.
Promise 앞에 await 키워드를 붙이면 자바스크립트는 Promise 가 처리될 때까지 대기하게 된다. 처리가 완료되면 조건에 따라 아래와 같은 동작이 이어지게 된다.
1️⃣ 에러 발생 – 예외가 생성됨(에러가 발생한 장소에서 throw error를 호출한 것과 동일함)
2️⃣ 에러 미발생 – Promise 객체의 result 값을 반환

사용 예시 코드

async function f() {

  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("완료!"), 1000)
  });

  let result = await promise; // Promise가 이행될 때까지 기다림 (*)

  alert(result); // "완료!"
}

f();
profile
예비 초보 개발자의 프로젝트와 공부 기록일지

0개의 댓글