비동기 그리고 에러처리

SOPT·2023년 1월 23일
0

server

목록 보기
2/2

비동기 처리를 사용하는 이유

비동기 처리는 앞선 작업이 끝난 후 다음 작업이 실행되는 동기와 달리, 앞선 작업의 완료 여부와 관계 없이 후에 이어지는 작업을 하는 방식입니다.

왜 작업을 순서대로 처리하지 않느냐 ? 라고 물으신다면, 작업을 한 개씩 처리하는 방식은, 업무는 단순할 수 있으나 자원이 비효율적으로 사용되기 때문입니다.

예를 들어, 일상에서 어떠한 프로그램을 다운하는 데 10분이 걸린다고 생각해봅시다. 우리는 자연스레 프로그램이 다운로드 되는 동안 다른 할 일을 할텐데요, 이것이 바로 비동기 처리입니다. 프로그램이 다운로드 되는 시간동안 우리는 동시에 다른 일을 하고 있으니까요 !

10분이 걸리는 다운로드를 동기적으로 처리한다면, 우리는 다운로드가 완료될 때까지 아무것도 못하고 하염없이 기다리게 될 것입니다. 비효율적이죠 ?

따라서, 웹 상에서 파일을 받아오거나, 데이터베이스 처리를 하는 등 시간이 상대적으로 오래 걸리는 작업을 할 때에는 비동기 처리를 할 수 있도록 하여, 오랜 시간 작업이 진행되는동안 다른 일을 할 수 있도록 합니다.


그러나 동기적 처리가 필요할 때가 있다 ?

위의 글을 읽어보면 그러면 동기는 왜 있나요 ? 할 수 있지만, 동기적 처리도 꼭 필요한 경우가 있습니다. A 작업의 결과인 a 정보를 사용하여 B에서 작업을 처리한다고 가정한다면, A 작업이 완료되지 않은 채 B 작업을 시작할 시 우리는 올바른 작업을 진행할 수 없겠죠 ?

따라서 우리는 상황에 따라 동기와 비동기를 적절히 사용할 줄 알아야합니다.


Promise 란 ?

콜백 함수를 사용하지 않고 비동기 처리를 하기 위해 JS에서 제공하는 object로, 성공과 오류에 대한 응답 처리로 이루어져 있습니다

우리는 promise를 사용할 때 , .then, .catch를 사용한다는 것을 세미나 때 배웠습니다. + finally까지 해서 조금 더 자세히 알아봅시다.

  • .then : 비동기 처리가 성공할 경우, resolve 내의 값을 받아온다
  • .catch : 비동기 처리가 실패하였을 때, reject 내의 값을 받아온다
  • .finally : 비동기 처리의 성공 여부와 관계 없이 실행하고자 하는 기능을 넣어준다
const promise = new Promise((resolve, reject) => {
  if (condition) {
    resolve("비동기 처리 성공");
  } else {
    reject("비동기 처리 실패");
  }
});

//* 비동기 처리 성공(then), 비동기 처리 실패(catch)
promise
    .then((resolvedData): void => console.log(resolvedData))
    .catch((error): void => console.log(error));
    .finally(() => {console.log("finally")})

자 위와 같은 코드가 있다고 가정해봅시다. 각각 condition이 true/false일 때의 실행 결과는 아래와 같습니다.

비동기 처리의 성공 여부와 관계 없이 finally 안의 코드가 실행되는 것을 확인할 수 있죠 !


promise chaining에서 .catch는 여러 번 써주어야 할까 ?

정답은 NO 입니다.

promise
.then()
.then()
.then()

위와 같은 promise chaining 코드에서 에러는 어디에서 발생할 지 모르죠.
이러한 경우 그러한 에러를 잡기 위해 모든 .then 다음에 .catch를 적어주어야하냐 ? 하면 아닙니다!

catch는 한 번의 사용으로 연결된 모든 promise에 대한 reject를 해결합니다.
따라서, 아래와 같이 한 번만 적어주셔도 괜찮습니다.

promise
.then()
.then()
.then()
.catch() // 이렇게 한 번만 써줘도 된다 !!

Error 반환 방법

우리는 위에서 reject 내에 error 시 반환할 문자열을 넣고, console.log 를 해주었습니다. (세미나 코드에서는 reject 내에 new Error(문자열) 형태로 되어있죠 !)

그러나, error을 console.log를 통해 출력해주는 것은 좋은 방식이 아닙니다.
다음 세 개의 문서에서 제가 소개할 내용에 대해 보다 자세한 내용을 다루고 있으니 참고 부탁드립니다. (전 아주 간략 of 간략으로 소개드릴 것 ,,)

Error 객체

throw

try-catch

짜잔,,

promise
.then((resolvedData): void => console.log(resolvedData))
.catch((error): void => {throw new Error(error)})
.finally(() => {console.log("finally")});

.catch 내의 (error)은 우리가 reject 내에 적어준 문자열일 것이며, 우리는 이를 Error 객체로 묶어 throw로 던져줍니다 !
throw는 의도적으로 에러를 직접 발생시키는 것이에요

세미나 때의 코드를 그대로 실행시킨다면 아래와 같이 Error가 보일텐데요,

위의 코드를 실행시키면 아래와 같이 뜹니다. 에러가 발생한 줄이 다르죠 ?? 위 결과에서 나타내는 11번째 줄은 reject(new Error(”~~”))가 있는 줄, 아래 결과의 18번째 줄은 .catch((error): void => {throw new Error(error)}) 가 있는 줄입니다 !

그렇다면 세미나 코드에서 조금 더 깔끔하게 Error을 출력하는 방법이 없을까 ! 한다면 error.nameerror.message에 대해 알고 계셔야 하는데요,

Error : 비동기 처리 실패 에서 Errorerror.name, 비동기 처리 실패 는 error.message에 해당합니다.

.catch((error): void => console.log(error.name,':',error.message))

따라서 위와 같이, error.nameerror.message만을 출력하게 해준다면 아래와 같이 깔꼼하게 볼 수 있습니다 !


작성자
IN SOPT, YB Server 박서원

profile
IT 대학생벤처창업동아리 SOPT의 공식 블로그입니다.

0개의 댓글