Asynchronous와 ajax
AJAX
Synchronous vs Asynchronous

| 특성 | 동기(Synchronous) | 비동기(Asynchronous) |
|---|
| 처리 방식 | 순차적 실행(단순한 코드 흐름) | 병렬적 실행(상대적으로 복잡한 코드 구조) |
| 자원 활용 | 단일 작업으로 인한 자원 비효율성 | 다중 작업 수행으로 인한 자원 효율성 |
| 대기 상태 | 다음 작업을 위해 대기 시간 발생 | 대기 시간 없이 다른 작업 수행 가능 |
| 코드 실행 | 위에서 아래로 순차적 실행 | 콜백함수나 프로미스 등을 통한 실행 |
| 적용 상황 | 간단한 연산이나 작은 규모의 데이터 처리 | 네트워크 요청이나 대용량 파일 처리 |
AJAX : Asynchronous JavaScript and XML
- 비동기로 처리되는 JavaScript와 XML (초창기는 XML을 데이터 교환 수단으로 사용함. 요새는 JSON)
- 주 사용처
- 화면 갱신 없이 클라이언트와 서버 간 XML, JSON, HTMML 등 정보

promise
Promise
Promise
- callback hell에 대한 대책으로 비동기 작업이 성공적으로 종료된 이후의 결과값 또는 실패 사유를 처리하기 위한 API

| 상태 | 설명 |
|---|
| pending | -실제 작업을 위한 준비 단계 -Promise 객체 생성 시 fulfilled,rejected 상황에서 호출할 handler 함수 바인딩 |
| fulfilled(이행,성공) | -동작이 성공적으로 완료된 상태 |
| rejected(거부,실패) | -동작이 실패한 상태 |
Promise 객체의 생성과 호출
- 비동기 작업을 정의하는 producing code와 결과를 활용하는 consuming code로 구분

const promise = new Promise(function(onfilfilled, onrejected) {do something})
promise.then(function(){}, function(){});
promise.then(function(){}.catch(){})
Producing Code
- Promise 함수 : 생성자에 executor 함수를 파라미터로 받음
- executor는 비동기 작업을 정의하는 콜백함수로 onfufilled와 onrejected 두 개의 콜백을 받음
- executor 내부에서 작업 성공 시 onfulfilled, 실패 시 onrejected를 호출하는 것을 약속!!
- onfulfilled가 호출되면 promise는 fufilled 상태로 되고 onrejected가 호출되면 promise는 rejected 상태가 됨
const promise = new Promise((onfufilled, onrejected) => {
setTimeout(() => {
if (pcheck.checked) {
onfulfilled(pcheck.checked);
} else {
onrejected(pcheck.checked);
}
}, 2*1000);
}
);
Consuming code
- 약속의 결과로 호출되는 코드 즉 비동기 작업의 결과를 활용하는 코드 작성
(method) Promise<any>.then<void, never>(
onfulfilled? : ((value:any) => void | PromiseLike<void>) | null | undefined,
onrejected?: ((reason: any) => PromiseLike<never>) | null | undefined) : Promise <...>
- 각각의 콜백은 파라미터를 하나씩 받는데
- onfufilled는 Promise가 정상 실행 되었을 때의 반환값, onrejected는 Promise가 reject된 이유
- return : 새로운 Promise 객체 - Promise Chaining 기능
(method) Promise<void>.catch<void>(
onrejected?: ((reason: any) => void | PromiseLike<void>) | null | undefined) : Promise<void>
- promise가 실패했을 때 실행할 콜백 onrejected를 파라미터로 받음
- onrejected 콜백에 전달되는 파라미터는 Promise가 reject된 이유
- return : 새로운 Promise 객체 : Promise chaining 기능
(method) Promise<void>.finally(
onfinally?: (() => void | null | undefined) : Promise<void>
- 성공 실패 여부와 상관 없이 언제나 호출되는 함수
- 파라미터 없는 onfinally()를 callback으로 받으면 Promise 객체 반환으로 Promise chaining 가능
promise chaining
- then, catch, finally 함수는 다시 Promise를 리턴하므로 지속적인 chaining 가능
- handle이 예외를 발생(a)시키거나 rejected된 promise(b)를 반환하는 경우 - 실패의 case
- 1외의 경우 (handler가 null, void, 특정 값이나 fufilled된 promise(b)를 반환하는 경우) - 성공의 경우
- handler가 새로운 pending된 promise를 반환하는 경우
- promise의 이행 여부와 결과값에 따라 다음 then/catch handler 연결

async, await
async~await
- then~catch의 문제점 : callback hell 다음의 then hell 유발
- async : 비동기 함수를 동기적으로 사용할 함수에 선언하며 async가 선언된 함수는 자동으로 Promise가 됨
- await : 실행을 대기할 Promise
- 반드시 async 함수 내에서만 사용
- fufilled의 parameter로 전달되는 값은 return으로 처리되며 rejected는 error 발생시켜 catch에서 처리
- 전체적으로 try ~ catch ~ finally 구문으로 사용
const simpleAsync = async() => {
try {
const result = await my Promise;
console.log("성공했군!!", result);
} catch (e) {
console.log("실패했군.. 왜?", e);
} finally {
console.log("아무튼 끝?", myPromise);
}
};
simpleAsync();
비동기의 동작 원리
JavaScript는 기본적으로 single thread model
- 기본적으로는 한 번에 하나의 동작만 처리 가능
- 하지만 기본적인 흐름과 비동기의 흐름이 마치 따로 존재하는 것처럼 보임
- JavaScript의 EventLoop와 TaskQueue의 동작으로 비동기 작업 처리

JavaScript runtime
- Call stack
- 함수를 호출할 때마다 실행 컨텍스트가 stack에 push되고 함수가 종료되면 pull
- call stack이 비어있지 않으면 어떠한 비동기 작업도 진행되지 않음 (call stack이 비어있어야 다른 비동기 작업 진행)
- Web API :
- 브라우저와 상호작용하는 부분으로 web api의 실제 동작은 JS 코드와는 별도로 동작
- 결국 multi thread처럼 동작하는 것은 브라우저에서 처리
- setTimeout 작업의 timeout 등으로 요청이 완료되면 연관된 call back 함수를 task queue에 추가
- TaskQueue
- Web API에서 처리된 비동기 작업의 callback 함수가 대기하는 큐
- Micro Task Queue
- Promise의 then, catch, finally 핸들러와 같이 좀 더 우선순위가 높은 비동기 작업이 대기하는 큐
- Event Loop
- Call Stack이 비어있을 때 Micro Task Queue > Task Queue를 확인하면서 대기중인 작업을 Call Stack에 추가
fetch API
fetch API
fetch API
- JavaScript에서 네트워크 요청을 수정하기 위해 사용하는 API로 Promise 기반으로 비동기 요청 처리
fetch API 요청
function fetch(input : RequestInfo | URL, init?:RequestInit) : Promise<Response>
- input : 필수 속성으로 정보를 가져올 대상의 URL
- init : 옵션 객체로 요청 시 추가로 전달할 내용 설정
- method : GET, POST 등 요청 방식으로 기본은 GET
- headers : 요청 header에 대한 설정으로 객체
- body : post 요청 시 request body를 통해서 전달할 내용
- body 타입에 따른 headers의 Content-Type 설정
| body타입 | 예 | headers |
|---|
| JSON문자열 | JSON.stringify({name:"John"}) | headers:{"Content-Type":"application/json"} |
| URLencoded문자열 | name=John&age=10 | headers:{"Content-Type":"application/x-www-form-urlencoded"} |
| FormData | constformData=newFormData();
formData.append("name","John"); | 자동설정(설정안함) |
fetch API 응답 처리
- 단계 1 : Response 객체 수신 단계
- 네트워크 장애 및 요청 실패 시 (헤더가 잘못 써지는 등 요청 구조적인 문제) 만 rejected이며 서버가 반응하면 fufilled 상태
- 필요하다면 세부적으로는 Response#status로 분기

- 단계 2 : Response에서 본문 내용 추출 단계
- 전달받은 body의 타입에 따라 response.json(), response.text(), response.blob()로 내용 수신
- 위 메서드들은 return 타입도 promise타입. 따라서 chaining을 통해 다시 한번 promise 처리