[React] 비동기 통신, Promise

js j·2023년 11월 24일
0

React

목록 보기
5/8
post-thumbnail

비동기 통신

초기에는 서버에서 모든 데이터를 로드하여 페이지를 빌드했으나 Ajax 기술의 등장으로 페이지 로드 없이 client-side에서 서버로 요청을 보내 데이터를 처리할 수 있게 되었다. XMLHttpRequest라는 객체를 이용해 서버로 요청을 보낼 수 있게 되었다.

자바스크립트는 single-threaded language이므로, 만일 서버 요청을 기다려야 한다면 유저는 멈춰있는 브라우저를 보게 될 것이다. 따라서 동기가 아닌 비동기 처리를 이용해 서버로 통신할 필요가 있다.

비동기 요청 후, main thread는 유저의 입력을 받거나, 페이지를 그리는 등의 작업을 처리한다.
비동기 응답을 받으면, 응답을 처리하는 callback 함수를 task queue에 넣는다. event queue는 main thread에 여유가 있을 때 task queue에서 함수를 꺼내 실행한다.

동기 비동기 차이점

동기 코드는 해당 코드 블록을 실행할 때 thread의 제어권을 넘기지 않고 순서대로 실행하는 것을 의미한다.

비동기 코드는 코드의 순서와 다르게 실행된다. 비동기 처리 코드를 감싼 블록은 task queue에 넣어딘다. main thread가 동기 코드를 실행한 후에 제어권이 돌아왔을 때 event loop가 task queue에 넣어진 비동기 코드를 실행한다.

비동기 처리에 내부 구조

브라우저에서 실행되는 자바스크립트 코드는 event driven 시스템으로 작동된다. 웹앱을 로드하면 브라우저는 HTML document를 읽어 문서에 있는 CSS code, JS code를 불러온다. 자바스크립트 엔진은 코드를 읽어 실행 된다.

브라우저의 main thread는 자바스크립트 코드에서 동기적으로 처리되어야 할 코드 실행 외에도, 웹 페이지를 실시간으로 렌더링하고, 유저의 입력을 감지하고, 네트워크 통신을 처리하는 등 수많은 일을 처리한다. 비동기 작업을 할당하면, 비동기 처리가 끝나고 브라우저는 task queue에 실행코드를 넣는다.

main thread는 event loop를 돌려, task queue에 작업이 있는지 체크하고 작업이 있으면 task를 실행



Promise

Callback pattern에 단점은 비동기 처리가 고도화되면서, Callback hell 등이 발생할 수 있다는 점이다. Promise를 활용하면 비동기 처리의 순서 조작, 에러 핸들링, 여러 비동기 요청 처리 등을 쉽게 처리할 수 있게 된다.

Callback pattern

function fetchUsers(onSuccess){
	request('/users', onSuccess)
}

Promise

function fetchUsers(onSuccess){
	return request('/users').then(onSuccess)
}

Promise 객체는, 객체가 생성 당시에는 알려지지 않은 데이터에 대한 Proxy, 비동기 실행이 완료된 후에 '.then', '.catch', '.finally' 등의 핸들러를 붙여 각각 데이터 처리 로직, 에러 처리 로직, 클린업 로직을 실행한다.
then 체인을 붙여, 비동기 실행을 마치 동기 실행처럼 동작하도록 한다.

Promise 객체는 pending, fulfilled, rejected 3개의 상태를 가진다. fulfilled, rejected 두 상태를 settled 라고 지칭한다.

pending - 비동기 실행이 끝나기를 기다리는 상태
fulfilled - 비동기 실행이 성공한 상태.
rejected - 비동기 실행이 실패한 상태.

then, catch는 비동기, 동기 실행 중 어떤 것이라도 리턴할 수 있다.

Multiple Promise Handling

Promise.all()은 모든 프로미스가 fulfilled 되길 기다린다. 하다라도 에러가 발생하면 모든 프로미스 요청이 중단된다.
Promise.allSettled()는 보든 프로미스가 settled 되길 기다린다.
Promise.race()는 넘겨진 프로미스들 중 하나라도 settled 되길 기다린다.
Promise.any()는 넘겨진 프로미스 중 하나라도 fulfilled 되길 기다린다.

profile
나의 코딩 일기

0개의 댓글