본 자료는 Elice 플랫폼의 자료를 사용하여 정리하였습니다.
자바스크립트 비동기 1
자바스크립트 비동기의 등장
- 초기
- AJAX의 등장으로 페이지로드없이 client-side에서 서버로 요청을 보내 데이터를 처리
- XMLHttpRequest라는 객체를 이용해 서버로 요청을 보낼 수 있게되었다.
자바스크립트와 비동기
- 자바스크립트는 side-threaded language 이므로, 만일 서버요청을 기다려야 한다면 유저는 멈춰있는 브라우저를 보게될 것
- 따라서 동기가 아닌 비동기 처리를 이용해 서버러 통신할 필요가 있다.
- 비동기 요청 후, main thread는 유저의 입력을 받거나, 페이지를 그리는 등의 작업을 처리한다.
- 비동기 응답을 받으면, 응답을 처리하는 callback함수를 task queue에 넣는다.
- event loop는 main thread에 여유가 있을 때 task queue,에서 함수를 꺼내 실행한다.
동기 vs 비동기
동기 코드
- 해당 코드블록을 실행할 때 thread의 제어권을 넘기지 않고 순서대로 실행
비동기 코드
- 코드의 순서와 다르게 실행된다.
- 비동기 처리 코드를 감싼 블록은 task queue에 넣어진다.
- main thread가 동기코드를 실행한 후에 제어권이 돌아왔을 때 event loop가 task queue에 넣어진 비동기 코드를 실행한다.
자바스크립트 비동기 2
비동기 처리를 위한 내부 구조
- 브라우저에서 실행되는 자바스크립트 코드는 event driven 시스템으로 작동
- 웹 앱을 로드하면 브라우저는 HTML document를 읽어 문서에 있는 CSS, JS code를 불러온다.
- 자바스크립트 엔진은 코드를 읽어 실행한다.
- 브라우저의 main thread는 자바스크립트 코드에서 동기적으로 처리되어야 할 코드실행외에도 웹 페이지를 실시간으로 렌더링하고, 유저의 입력을 감지하고, 네트워크 통신을 처리하는 등 수많은 일처리를 한다.
- 비동기 작업을 할당하면, 비동기 처리가 끝나고 브라우저는 task queue에 실행코드를 넣는다.
- main thread는 event loop를 돌려, task queue에 작업이 있는지 체크한다.
- 작업이 있으면 task를 실행한다.
Promise
Callback pattern vs Promise
- 비동기 처리 후 실행될 코드를 Callback function으로 보내는 것
- 비동기 처리가 고도화 되면서, Callback hell 등이 단점으로 부각된다.
- Promise를 활용하여 비동기 처리의 순서 조작, 에러 핸들링, 여러 비동기 요청 처리등을 쉽게 처리
Promise
- Promise 객체는, 객체가 생성 당시에는 알려지지 않은 데이터에 대한 Proxy.
- 비동기 실행이 완료된 후에,
.then
, .catch
, .finally
등의 핸들러를 붙여 각각 데이터 처리 로직, 에러 처리 로직, 클린업 로직을 실행
- then체인을 붙여, 비동기 실행을 마치 동기실행처럼 동작하도록 한다.
Promise의 상태
- pending : 비동기 실행이 끝나기를 기다리는 상태
- fulfilled : 비동기 실행이 성공한 상태
- rejected : 비동기 실행이 실패한 상태
- fultilled와 rejected는 합쳐서 settled라고도 한다.
Promise의 then, catch
- then, catch는 비동기(Promise), 동기 실행 중 어떤 것이라도 리턴할 수 있다.
Multiple Promise handling
Promise.all()
은 모든 프로미스가 fulfilled 되길 기다린다.
- 하나라도 에러 발생 시, 모든 프로미스 요청이 중단된다.
Promise.allSettled()
는 모든 프로미스가 settled 되길 기다린다.
Promise.race()
는 넘겨진 프로미스들 중 하나라도 settled 되길 기다린다.
Promise.any
는 넘겨진 프로미스 중 하나라도 fulfilled 되길 기다린다.
Promise chaining, nested promise
- Promise 객체는, settled 되더라도 계쏙 핸들러를 붙일 수 있다.
- 핸들러를 붙인 순서대로 호출된다.
.catch
뒤에 계속 핸들러가 붙어있다면, 에러를 처리한 후에 계속 진행된다. 이때는 catch에서 리턴한 값이 then으로 전달된다.
async/await
async/await
- Promise 체인을 구축하지 않고도, Promise를 직관적으로 사용할 수 있는 문법
- 많은 프로그래밍 언어에 있는 try...catch 문으로 에러를 직관적으로 처리
- async function을 만들고, Promise를 기다려야 하는 표현 앞에 await를 붙인다.
async/await - Promise와의 조합
- Promise.all은 특정 비동기 작업이 상대적으로 빠르게 끝나도, 느린 처리를 끝까지 기다려야만 한다.
- async/await는 끝난대로 먼저 처리할 수 있다.
POSTMAN, OpenAPI, CORS
POSTMAN 소개
- 서버와의 통신을 위해API를 활용하는 경우, React앱으로만 요청하여 API동작을 체크하는건 비효율적
- 수많은 API의 endpoint와 실행조건 등을 관리하는 것도 힘들다.
- POSTMAN은 API를 테스트하기 위한 개발도구
- Auth, header, payload, query등 API요청에 필요한 데이터를 쉽게 세팅
- 다른 개발자가 쉽게 셋업해 테스트할 수 있도록 API정보를 공유할 수 있다.
- Request를 모아 Collection으로 만들어 API를 종류별로 관리
- 환경변수를 정의하여, 환경별로 테스트 가능
OpenAPI
- Restful API를 하나의 문서로 정의하기 위한 문서 표준
- Open API Specification(OAS)으로 정의됨
- Swagger 등의 룰로, OpenAPI로 작성된 문서를 파생해 테스팅 도구로 만들 수 있다.
- 프론트엔드 개발자, 백엔드 개발자와의 협업 시 주요한 도구로 사용
- API의 method, endpoint를 정의
- endpoint 마다 인증방식, Content type등 정의
- body data, query string, path variable등 정의
- 요청, 응답 데이터 형식과 타입 정의-data model의 활용(Schema)
CORS
- Cross-Origin Resource Sharing
- 브라우저는 모든 요청 시 Origin헤더를 포함
- 서버는 Origin헤더를 보고, 해당 요청이 원하는 도메인에서부터 출발할 것인지를 판단
- 다른 Origin에서 온 요청은 서비에서 기본적으로 거부한다
- 그러나, 보통서버의 endpoint와 홈페이지 domain은 다른 경우가 많다.
- 따라서 서버에서는 홈페이지 doman을 허용하여, 다른 domain이라 하더라도 요청을 보낼 수 있게한다.
- 서버는 Access-Contol-Allow-Origin 외에 Access-Contol-* 을 포함하는 헤더에 CORS 관련정보를 클라이언트로 보낸다
- 웹사이트에 악성 Script가 로드되어, 수상한 요청을 하는 것을 막기 위함이다.
- 반대로, 익명유저로부터 DDoS공격 등을 막기 위함이다.
- 서버에 직접 CORS설정을 할 수 없다면, PoXy서버 등을 만들어 해결