💙 들어가며
Ajax를 지원하는 또 다른 방식
프라미스에 대해서 배워보자!
✏️ 학습내용 정리
#동기와 비동기
코드는 쭈욱 일렬로 나열되어 있다.
그러나 어떤 코드는 처리시간이 오래 걸리고,
어떤 코드는 바로 처리될 수도 있다.
모든 코드를 다 순차적으로 실행하려다보면
특정 부분에서 걸려서 응답이 늦어지는 문제가 생기게 된다.
그래서 동기(순차적)으로 처리되는 것과
비동기적(비순차적)으로 처리되는 것이 필요하다.
비동기적(비순차적)으로 처리된다고 하면
흐름이 2가지가 된다는 뜻이다.
내 눈앞에 보이는 코드 중에 일부가
다른 흐름에 들어가있다고 한다면
끝나는 시점을 어떻게 알 수 있을까?
(비동기 작업이 끝났다는 것은 어떻게 알 수 있을까?)
우리는 이전에 콜백함수를 사용하여
비동기 작업이 끝났는지 확인하고
필요한 return값을 받았다.
하지만 이렇게 되면
함수를 호출하는 것보다 함수를 처리하는 부분이
점점 길어지고 중첩이 이어지게 된다.
그래서 이 중첩을 마치 수직방식으로
처리하고 싶은 바람이 생기게 되었고, (동기처럼)
이것이 프라미스를 통해서 가능하게 되었다!
#프라미스(Promise)란?
💡 프라미스(Promise)란?
비동기 작업에 대한 완료, 실패를 결과값으로 알려주는 객체이다.
(비동기의 반환값을 책임지는 객체!)
이벤트가 완료되면 실행하는 것을 약속해주겠다. (대리자)
(EX)
비동기 함수 호출했어?
걔가 완료되면 내가 호출할게, 나한테 줘.
비동기 처리를 통한 함수의 반환값은
return으로 반환받을 수 없다.
return을 할 때까지 기다려주지 않기 때문이다.
(동기 처리에서만 return이 가능하다.)
그래서 콜백함수로 비동기처리에 대한
반환값을 받았는데,
콜백의 chain이 계속 되면서
중첩되는 형태의 비동기 처리 구조가 만들어졌고
코드의 복잡도가 높아졌다.
이것에 대한 대한 대응책이
프라미스 객체를 반환하는 것이다.
#콜백함수와 프라미스
콜백과 프라미스의 느낌은 어떻게 다를까?
함수를 호출하는 부분과
함수를 처리하는 부분이 겹치지 않고 분리되었다.
위의 코드를 보면 resultCallback이라는 함수를
전달하지 않았는데, 처리되었다.
콜백을 어떻게 호출할 수 있었을까?
콜백을 호출해줄 수 있는 약속해놓은 객체가 프라미스이다.
비동기처리는 바로 처리 함수를 받거나(콜백)
혹은 처리해줄 수 있는 객체를 반환(프라미스)하는 방법으로
처리할 수 있다고 정리할 수 있겠다.
사용하려는 API가
콜백함수를 지원하는지, 프라미스를 지원하는지
확인해서 비동기처리를 하면 되겠다.
(예시: Node.js -> filesystem관련 api들 동기 포함 3개 다 지원)
💡 Ajax(XHR API와 Fetch API)
request 도구로 XHR를 선택하나 Fetch를 선택하나 상관없다.
둘 다 존재하니 원하는 기능을 택하여 사용하면 된다.
둘 다 브라우저에서 지원하는 기본 플랫폼 라이브러리이다.
출처: 이전 게시글
#Fetch API: 프라미스로 비동기 처리
두 가지의 차이에 대해서 이해했다면
콜백기반의 도구인 XHR말고,
프라미스 기반의 도구 Fetch를 사용해보자.
직접 get이라는 함수를 정의하지 말고
fetch라는 함수를 사용해보자.
함수를 전달할 필요 없이 url만 전달하면 된다.
let promise = fetch(`http://localhost:8080/api/menus`);
⭕ 출력결과
요청에 반응해서 fetch가 반환하는 녀석인 response이다.
기존의 JSON형태와는 다른 모양새이다
response.body를 반환한다.

응답으로 온 것이 잘 온것인지에 대한
상태값을 가지고 있는
response라는 객체를 반환했다.
JSON형식으로 응답 온 결과값을 얻을 수 있으려면
반환된 response라는 객체에
response.json()이라는 메소드를 사용하면 된다.
json형식으로 변환해준다.
#프라미스 객체 전달받기
프라미스를 사용하면 중첩이 필요 없어진다.
.then()절을 이용하여
이전에 .then절에서 반환한 값을
받을 수 있기 때문이다!
(아래 부분에서 this부분 오타임 list임)
즉 이제는 직접 함수를 정의할 필요 없다!
fetch api사용하면 됨!
#.then()절: 미들웨어 시스템
프라미스만 리턴하는 것 같지만 아니다.
중간에서 암호화를 하거나 바꾸는 값을
중간에 꼈다가 뺄 수 있는
미들웨어 시스템을 지원한다.
필요하면 여러번 나눌 수 있고, 여러번 거칠 수 있다.
#동기형으로 써보자: await
await를 사용하게 되면
fetch함수에게
프라미스 형태로 반환하지 말고
결과값을 달라고 하는 것이다.
await는 메인스레드에서 사용하는 함수가 아니라 (ui 스레드)
비동기 스레드에서만 처리되는 녀석이다. (이벤트 스레드)
await는 동기형으로 처리하기위해
일부러 처리가 완료되게 하는 것이기 때문에
메인 스레드에서 처리되면
페이지가 다운되는 등의 문제가 생길 수 있다.
따라서 함수 안에서만 실행이 되도록 했다.
하지만 위에서도 언급했듯이
await는 비동기 스레드에서만 처리되는 녀석이기 때문에
await를 품고 있는 함수는 비동기 함수이어야 한다.
그래서 함수 앞에 비동기라는 것을 명시해주기 위해
async라는 예약어를 붙여야 한다.
button.onclick = async function(){ //function앞에 async붙여야
let response = await fetch(`http://localhost:8080/api/menus`); //await 사용 가능
let list = await response.json();
console.log(list);
}
⭕ 출력결과
resoponse와 list 2개의 변수만으로
json형태로 반환된 값을 바로 받을 수 있다..!

#(번외)Promise와 Fetch API는 별개이다.
프라미스는 범용도구이다.
꼭 비동기 함수에만 써야한다거나
fetch api랑 써야한다거나 하는 것이 아니다.
언제든지 빼야 하는 로직이 필요할 때
하나의 코드블럭을 사용해서 처리했다면
어려웠을테지만,
프라미스를 사용하면
쉽게 뺐다 꼈다 할 수 있다.
#(번외)람다식 간단하게 표현하기
return값만 있는경우에는 더 간단하게 표현이 가능하다.
#async 함수의 scope
async하는 위치도 잘 생각하자.
async를 붙이면 스레드가 달라지기 때문에
동기 스레드에서 값을 공유하는 녀석이 있다면
공유받지 못해서 오류가 날 수 있다.
💙 들어가며
1.
아래 변수의 이름을 달라질 수 있다.
.then을 붙여서 순서대로 나오는 것
response: fetch해서 처음 나오는 값 (응답 결과)
promise: response.json()을 해서 나오는 값 (promise객체)
array: promise를 최종 파싱한 형태, 그냥 .then절 한 번더 붙여서 사용하면 알아서 파싱됨