비동기처리: callback 함수 & Promise
1. 동기와 비동기
1) Synchronous(동기적, 자바스크립트는 동기적 언어) : 호이스팅 된 이후부터 코드가 작성한 순서대로 동기적으로 실행되는 것
- 호이스팅? var변수, function함수같은 선언들이 제일 위로 올라가는 것
2) Asynchronous(비동기적): 언제 코드가 실행될지 예측할 수 없는 것
비동기적 실행 방법
ex)
setTimeout(): 브라우저에서 제공되는 웹 API로 지정한 시간이 지나면 전달한 콜백 함수 호출

=> 1, 3, 2 출력 ('2'는 1초 뒤 콘솔 출력)
2. 콜백 함수
callback
- 지금 당장 실행하지는 않고 나중에 불러달라, 함수를 실행해달라는 함수
- () => 으로 일일이 함수를 선언하지 않고, 간단하게 전달할 수 있음
콜백 2가지 경우
1) 동기적 콜백(Synchronous Callback)
: 즉각적으로 동기적으로 실행하는 콜백

=> 1, 3, hello, 2 출력
printImmediately()함수 선언이 제일 위로 올라가고
1, 3 출력
2 브라우저에 요청
hello 출력
2 출력
2) 비동기적 콜백(Asynchronous Callback)
: 언제 실행될지 예측할 수 없는 콜백

setTimeout(콜백 함수 호출, 인자 전달);
=> 1, 3, hello, 2, async callback 출력
콜백 지옥?
※콜백 지옥 = 콜백 체인의 문제점
- 가독성이 너무 떨어짐, 읽기 힘들다.
- 어디서 어떤식으로 연결되어있는지 한눈에 보기 어려움, 비즈니스 로직 한눈에 알아보기 어려움
- 콜백 체인이 길어질수록 에러 발생하거나 디버깅, 유지보수 등이 어려워짐
Promise
약속
- 자바스크립트에서 제공하는 비동기를 간편하게 처리할 수 있도록 도와주는 오브젝트이며, 콜백함수 대신 유용하게 쓸 수 있음
- 실행: 정해진 장시간의 기능을 수행하고 나서 정상적으로 기능이 수행되어졌다면 성공 메시지와 함께 처리된 결과값 전달(promise가 성공적으로 값 전달) or 문제발생 시, 에러 전달
Point⭐
1) State(상태)
이 프로세스가 무거운 것을 수행하고 있는 중인지 or 기능 수행 완료가 돼서 성공했는지, 실패했는지 상태
2) Producer와 Consumer의 차이점
우리가 원하는 데이터를 제공하는 사람(Producer)과 제공된 데이터를 쓰는 사람(Consumer)
- Producer: 우리가 원하는 기능을 수행해서 해당하는 데이터를 만들어내는 역할(Promise Object)
- Consumer: 우리가 원하는 데이터를 소비하는 역할
1) Promise State
state: pending -> fulfilled or rejected
- pending: promise가 만들어져서 우리가 지정한 오퍼레이션이 수행 중일 때
- fulfilled: 이 오퍼레이션을 성공적으로 다 끝내게된 후, 완벽하게 완료된 상태 or
- rejected: 파일을 찾을 수 없거나 네트워크에 문제가 생겼을 때 상태
2) Producer와 Consumer
1. Promise 만들기 (Producer)
원하는 기능을 비동기적으로 실행하는 promise 만들기(비동기적으로 수행하고 싶은 기능 코드 작성)
// 1.Producer
const promise = new Promise((resolve, reject) => { // promise = class이므로 new로 오브젝트 생성
setTimeOut(() => {
resolve('ellie'); //성공적인 경우 resolve 콜백 함수 호출
//자바스크립트에서 제공하는 object (에러가 발생했다는 걸 나타낸 object)
reject(new Error('no newtwork')) // 어떤 에러인지 명시적으로
}, 2000);
});

=> 잡히지 않은 에러 발생
구조
executor콜백 함수 안에 또 다른 콜백 함수(resolve, reject)를 받음
- resolve: 기능을 정상적으로 수행해서 마지막에 최종 데이터를 전달하는 콜백함수
- reject: 기능을 수행하다가 중간에 문제가 생기면 호출하는 콜백함수
실행
promise를 만드는 순간, 우리가 전달한 executor(resolve, reject) 함수가 자동적으로 바로 실행
만약, promise안에 네트워크 통신하는 코드를 작성했다면, 네트워크 요청을 사용자가 요구했을 때만 해야되는 경우(ex.사용자가 버튼을 눌렀을 때 요청해야하는 경우), 사용자가 요청하지 않았는데 불필요한 네트워크 통신이 일어남
사용
네트워크에서 데이터를 받아오거나, 파일에서 큰 데이터를 읽어오는 과정은 시간이 꽤 걸림
=> 이런것을 동기적으로 처리하면 그 다음 라인의 코드가 실행되지 않으므로,
이렇게 시간이 오래걸리는 것은 promise를 만들어서 비동기적으로 처리하는 것이 좋음
2. Promise 사용하기 (Consumer 만들기)
Consumers: then, catch, finally를 이용해서 값을 받아올 수 있음
// 2.Consumer
// promise가 정상적으로 수행된다면(then),resolve 콜백함수에서 전달된 (ellie)값을 파라미터인 value로 받음
promise.then((value) => {
console.log(value);
})
// promise에 then을 호출하게되면
// 똑같은 promise가 return되므로 그 return된 promise의 catch를 다시 호출
// error가 발생했을 때, 어떻게 처리할건지 콜백함수 등록
.catch(error => {
console.log(error);
});
// 성공 실패와 상관없이 어떤 기능을 마지막으로 수행하고 싶을 때 사용
.finally(() => {
console.log('finally'); // 아무런 인자 받지않고, finally 무조건 호출
});
에러인 경우, 받아온 에러가 콘솔에 찍힘 (잡히지 않는 error를 catch로 잡음)

finally는 항상 호출됨
3. promise 연결하기

※then은 값을 바로 전달할 수도 있고, 또 다른 비동기인 promise를 전달해도 됨
=> 2초 후, 5 출력
4. 오류 처리하기
총 3가지의 promise를 return하는 함수

※ 콜백함수를 전달할 때 받아오는 value를 다른 함수 한 가지만 받아서 그대로 전달하는 경우 생략 가능
(then에서 받아오는 value를 바로 getEgg함수에 전달해서 호출)

console

catch로 오류 확인


오류 해결


발생하는 에러를 처리하고 싶을 때는 바로 그 다음에 .catch 작성해서 바로 문제 해결 가능