1. 자바스크립트 비동기1
등장
- 초기 웹 환경에서는, 서버에서 모든 데이터를 로드하여 페이지를 빌드했으므로 자바스크립트에는 별도의 비동기 처리가 필요하지 않았음.
- Ajax 기술의 등장으로 페이지 로드 없이 client-side에서 서버로 요청을 보내 데이터를 처리할 수 있게 됨.
- XMLHttpRequest라는 객체를 이용해 서버로 요청을 보낼 수 있게 됨.
자바스크립트와 비동기
- 자바스크립트는 single-threaded language이므로, 만일 서버 요청을 기다려야 한다면 유저는 멈춰있는 브라우저를 보게 될 것.
- 따라서 동기가 아닌 비동기 처리를 이용해 서버로 통신할 필요가 있음.
- 비동기 요청 후, main thread는 유저의 입력을 받거나, 페이지를 그리는 등의
작업을 처리.
- 비동기 응답을 받으면, 응답을 처리하는 callback 함수를 task queue에 넣음.
- event queue는 main thread에 여유가 있을 때 task queue에서 함수를 꺼내 실행.
동기
- 해당 코드 블록을 실행할 때 thread의 제어권을 넘기지 않ㅇ고 순서대로 실행하는 것을 의미
비동기
- 코드의 순서와 다르게 실행
- 비동기 처리 코드를 감싼 블록은 task queue에 넣어짐
- main thred가 동기 코드를 실행한 후에 제어권이 돌아왔을 때 event loop가 task queue에 넣어진 비동기 코드를 실행함.
2. 자바스크립트 비동기2
비동기 처리를 위한 내부 구조
- 브라우저에서 실행되는 자바스크립트 코드는 event driven 시스템으로 작동.
- (이벤트 드리븐 ? = task queue에 이벤트를 넣어 하나씩 실행하는 시스템을 말한다.)
- 웹앱을 로드하면 브라우저는 HTML document를 읽어 문서에 있는 CSS code, JS code를 불러옴.
- 자바스크립트 엔진은 코드를 읽어 실행.
- 브라우저의 main thread는 자바스크립트 코드에서 동기적으로 처리되어야 할 코드 실행 외에도, 웹 페이지를 실시간으로 렌더링하고, 유저의 입력을 감지하고, 네트워크 통신을 처리하는 등 수많은 일을 처리.
- 비동기 작업을 할당하면, 비동기 처리가 끝나고 브라우저는 task queue에 실행 코드를 넣음.
- main thread는 event loop를 돌려, task queue에 작업이 있는지 체크.
- 작업이 있으면 task를 실행.
3. Promise
Callback pattern vs Promise
- 비동기 처리 후 실행될 코드를 Callback function으로 보내는 것.
- 비동기 처리가 고도화되면서, Callback hell 등이 단점으로 부각됨. - Promise를 활용하여 비동기 처리의 순서 조작, 에러 핸들링, 여러 비동기 요청 처리 등을 쉽게 처리할 수 있게 됨.
promise
- Promise 객체는, 객체가 생성 당시에는 알려지지 않은 데이터에 대한 Proxy.
- 비동기 실행이 완료된 후에,
.then
, .catch
, .finally
등의 핸들러를 붙여 각각 데이터 처리 로직, 에러 처리 로직, 클린업 로직을 실행.
- then 체인을 붙여, 비동기 실행을 마치 동기 실행처럼 동작하도록 함.
returnPromise()
.then(num => {
console.log("First random number : ", num) })
.catch(error => {
console.error("Error occured : ", error)
})
.finally(() => {
console.log("Promise returned.")
})
상태
-
Promise 객체는 pending, fulfilled, rejected 3개의 상태를 가짐.
-
fulfilled, rejected 두 상태를 settled 라고 지칭.
-
pending은 비동기 실행이 끝나기를 기다리는 상태.
-
fulfilled는 비동기 실행이 성공한 상태.
-
rejected는 비동기 실행이 실패한 상태.
다중 promise 핸들러
- Promise.all()은 모든 프로미스가 fulfilled 되길 기다림. 하나라도 에러 발생시, 모든 프로미스 요청이 중단됨.
- Promise.allSettled()는 모든 프로미스가 settled 되길 기다림.
- Promise.race()는, 넘겨진 프로미스들 중 하나라도 settled 되길 기다림.
- Promise.any() - 넘겨진 프로미스 중 하나라도 fulfilled 되길 기다림.
4. async/await
- Promise 체인을 구축하지 않고도. promise를 직관적으로 사용할 수 있는 문법.
- try...catch 문으로 에러를 직관적으로 처리
- async function을 만들고, promise를 기다려야하는 표현 앞에 await을 붙임.
여러 개의 await
- 여러 개의 await을 순서대로 나열하여, then chain을 구현할 수 있음.
- try... catch 문을 자유롭게 활용하여 에러 처리를 적용.
5. POSTMAN, Open API, CORS
postman
- 서버와의 통신을 위해 API를 활용하는 경우 활용
- API를 테스트하기 위한 도구
- 포스트맨 짱짱맨!
open API
- RESTful API를 하나의 문서로 정의하기 위한 문서 표준
CORS
- Cross-Origin Resource Sharing.
- 브라우저는 모든 요청 시 Origin 헤더를 포함.
- 서버는 Origin 헤더를 보고, 해당 요청이 원하는 도메인에서부터 출발한 것인지를 판단.
- 다른 Origin에서 온 요청은 서버에서 기본적으로 거부함.
- 웹사이트에 악성 script가 로드되어, 수상한 요청을 하는 것을 막기 위함.
- 반대로, 익명 유저로부터의 DDos공격 등을 막기 위함.
- 서버에 직접 CORS 설정을 할 수 없다면, Proxy 서버 등을 만들어 해결.