동기, 비동기, Promise, async과 await

dolphinSarah·2021년 2월 8일
0
post-thumbnail

흐름 이해하기

동기 vs 비동기

요청하고 응답 받는 시간을 하나의 box라고 한다면, 동기는 box 안에서 움직이고, 비동기는 box를 벗어나 작동한다고 생각하면 된다. 조금 더 쉽게 설명해보겠다.

동기는 요청과 응답이 같은 시간대 안에 고정되어 있어서, 요청에 대한 응답이 완료되기까지 프로그램이 정지한다. 응답을 받고 나서야 프로그램이 다시 진행된다.

비동기는 요청과 응답 간의 결합이 자유로워서 프로그램이 응답 받기 위해 대기하지 않는다. 언젠가는 응답을 받을테니 다음 로직을 수행하는 식이다.

동기

요청을 하는 시기와 응답을 받는 시기가 일치한다. 간단히 말해, 요청을 하면 바로 응답을 받는다는 뜻이다. 하지만 응답을 즉시 받을 수도 있고, 그렇지 않을 수도 있다. 왜냐하면 요청을 받는 곳의 처리 속도가 어떤지는 아무도 알 수 없기 때문이다. 이러한 이유로 프로그램은 응답까지 대기 시간을 필요로 한다. 즉, 어플리케이션이 응답이 올 때까지 잠시 멈춘다는 의미이다.

비동기

요청한 내용을 언젠가는 응답해줄 것이라는 약속을 말한다. 요청과 응답이 다른 시간대에 존재하기 때문에, 요청 내용에 대해 지금 바로 응답받지 않아도 된다. 물론 바로 응답이 와도 된다.

Callback 함수

callback 함수는 자바스크립트의 비동기성을 표현하고 관리하는 가정 일반적인 기법이자 가장 기본적인 비동기 패턴이라고 한다. callback 함수는 call + back. '요청 처리가 완료되었으니 다시 사용하라'는 신호다. 예를 들어 떡볶이를 집에 사가려고 하는데, 배달이 밀려 시간이 좀 걸린다고 한다. 이때, 나는 전화번호를 주고 조리가 끝나면 받아갈테니 포장이 완료되면 전화를 달라고 했다. 즉, 일을 다른 객체에게 시키고 그 일이 끝날 것을 기다리는 게 아니라, 그 객체가 다시 나를 부를때까지 내 할일을 하고 있는 것이다.

Promise

Promise 도입 목적

비동기 처리는 함수에서 처리된 결과 값을 반환할 경우, (비동기) 함수에서 찾을 수 밖에 없어 코드가 복잡할 경우(Callback 지옥) 어려움이 있다. Promise는 구조가 간단해 반환값을 찾아 사용하기가 쉽다.

pending

비동기 처리 로직이 아직 완료되지 않은 상태. new Promise로 Promise가 생성된 직후부터 resolve나 reject가 호출되기 전까지의 순간을 pending이라고 한다.

fulfilled

처리가 완료되어 promise가 결과값을 반환한 상태. 만약 비동기 처리 함수 값이 성공이라면 resolve 메소드가 호출되고, resolve 메소드의 인자로 설정한 비동기 함수의 결과 값이 전달된다. 이 결과값은 then을 통해 후속 처리된다.

rejected

처리가 실패하거나 오류가 발생한 상태

async & await

기존의 비동기 처리 방식인 callback함수와 promise의 단점을 보완하고, 개발자가 읽기 좋은 코드를 작성할 수 있게 도와준다.

두 logName을 비교해보자. 하나는 async & await이 적용되었고, 다른 하나는 적용되지 않았다. 어떤 코드가 보기 편한가?

당연히 콜백을 사용하지 않은 아래의 코드, async & await이 적용된 코드가 보기 편하다!

그렇다면 async await의 기본 문법을 알아보겠다.

먼저, 함수 앞에 async라는 예약어를 붙인다. 그리고 함수의 내부 로직 중 HTTP 통신을 하는 비동기 처리 코드 앞에 await을 붙인다.

여기서 주의할 점은, 비동기 처리 메서드가 꼭 promise 객체를 반환해야 await가 의도한대로 동작한다.

일반적으로 await의 대상이 되는 비동기 처리 코드는 Axios 등 promise를 반환하는 API 호출 함수이다.

fetchItems()는 Promise 객체를 반환하는 함수다. await를 사용하지 않았다면 데이터를 받아온 시점에 콘솔을 출력할 수 있게, 콜백함수나 .then() 등을 사용해야 했을 것이다.

async & await 예외 처리

Promise에서 에러 처리를 위해 .catch()를 사용하는 것처럼 async에서는 catch{}를 사용하면 된다.

코드를 실행하다가 발생한 네트워크 통신 오류 뿐 아니라 간단한 타입 오류 등의 일반적인 오류까지도 catch로 잡아낼 수 있다. 발견된 error는 error 객체에 담기기 때문에 error의 유형에 맞게 error 코드를 처리해주면 된다.

profile
Exploring Front-end_.

0개의 댓글

관련 채용 정보