[JS] Promise & Async/Await
Callback
- 우리가 흔히 사용하는 콜백! 콜백이 뭐냐고 하면, 요청 후에 응답이 오면 요걸 수행해줘 같은 느낌
- 요청의 응답이 오기를 매번 주구장창 기다리면 어플리케이션이 너무 느려짐
- 그래서 비동기로 요청만 띡 보내고, 응답이 오기까지 기다리는게 아니라, 일단 다음꺼 수행하는 방식으로 수행함
- 비동기로 요청 보내는건, jquery ajax로 많이들 함.
- 응답이 와야지만 처리가 가능한건, ajax에 onSuccess, onFail 등 이벤트 달아서 요청 이후 작업처리 함
- 근데 문제는 이런 ES5 스러운 jquery ajax 쓰면 콜백헬이 발생함
- 콜백헬: .onSuccess(.onSuccess(.onSuccess(....
- 이벤트 처리 안에 이벤트 처리 안에 이벤트..
-> 코드 가독성도 떨어지고 짜기도 어렵고 indent도 레전드됨
-> 타파하기 위해 ES6에서는 Promise
를 내세우고, ES8에서는 Promise 마저 더 잘 사용할 수 있게하기 위해 Await/Async
등 새로운 개념을 가져오는데,, !
Promise
- 얘는 최종적으로 resolve() 나 reject()를 호출하는 메소드? 라고 생각하면 될듯함

- 저렇게 new Promise() 해서 promise 객체를 생성하는데,
- promise 파라미터로는
resolve
, reject
를 parameter로 갖는 function
- function 내에서 다음을 계속 수행했으면 좋겠는 경우 (success 느낌)에는
resolve(response)
를 해주면 되고, 문제 발생으로 수행을 그만할 경우 (fail 느낌)에는 reject(response)
를 해주면 된다.
- 일단 장점부터 얘기하자면, promise는 .then()으로 chaining 이 가능해서, 콜백헬이 만들어지지 않음
getData(userInfo).then(parseValue).then(auth).then(diaplay);
- promise에서 resolve 불렸을 경우, then을 수행,
- then 안에도 프로미스가 있을 경우, 해당 프로미스의 resolve가 불리면 그 다음 then을 수행.
- resolve가 아니고 reject가 불리면? -> .then()이 아니라, .catch() 내용이 수행됨
- 물론 then에서 function 하나 더 줘서 에러 catch할 수도 있는데 여러 단점이 있어서.. .catch() 로 잡는 것이 바람직해보인다. (여러 단점은 맨 아래 출처 url 참고)

요약
- promise는 resolve()나 reject()를 호출한다!
- resolve()냐 reject()냐에 따라서 .then()을 수행하냐, .catch()로 가냐 달라진다!
- promise 파라미터의 함수 안에서 콜백을 정의하는 것이 아니라, .then() 내부에서 콜백을 정의한다!
- chaining으로 콜백헬을 피할 수 있다!
Await/Async
- .then()으로 chaining 하는 것 조차 힘들고, .then()이고 뭐고 그놈의 ({도 안쓰고, 그냥 비동기 결과 동기처럼 받아볼수는 없나? request()가 비동기 요청이긴 한데, 그냥 var res = request(); 하고 console.log(res.id()) 하면 나오면 좋겠어..
- 그걸 가능하게 해주는 키워드: await/async

- async를 function 앞에 붙이는건, 해당 함수는 비동기로 사용하겠다고 명시하는 것.
- async 키워드가 붙은 function을 일반 로직에서 부른다면, 부르기만 하고 바로 다음 로직을 수행함. (논블로킹)
- await가 유효하려면, async function 안에서만 가능함!
일단 비동기여야지 기다리던, 콜백처리를 하던 하니까!
- await는 async함수의 실행을 중단하고, promise의 완료를 기다림
- promise가 rejct되면, await는 reject된 값을 throw
- 볼드 처리해둔게 가능하게 하려면
- function 앞에 async 키워드로, 요 function 내부에서 비동기 call이 일어난다는걸 명시해줘야함.
- 실제 비동기 call 앞에 await를 붙여서, 비동기 call 결과가 올때까지 blocking 시켜야함. 기다려~~ 라는 뜻.
- 끝내 비동기 call 결과가 나오면, 그때 아래의 로직들 수행
- .then()도 안쓰고, chaining도 안쓰고 비동기 후 콜백 처리를 이렇게 동기처럼 쉽게 할 수 있어졌다!
- 근데 위의 사진에서 async/await 빼면 뭐가 달라져?
- fetchUser() 부르고 응답 오기 전에 아래 if로 넘어가서 user가 뭐야? undefined임 퉤 하고 뱉어냄
- 주의할 점: await가 정상작동하려면 Promise여야 붙일 수 있습니다.
- 원문: 여기서 주의하셔야 할 점은 비동기 처리 메서드가 꼭 프로미스 객체를 반환해야 await가 의도한 대로 동작합니다.
- 왜냐하면 await는 promise가 처리되기까지를 기다리기 때문에, 프로미스가 없으면 기다려주지 않습니다~
- await 연산자 다음에 나오는 문의 값이 Promise가 아니면 해당 값을 resolved Promise로 변환시킵니다 (기대하는대로 동작 X)
- promise의 .then() chaining에서는 .catch()로 잡았는데.. 얘는 예외 어떻게 잡나요
- try {await 폭탄} catch (err) {} 하면 됩니다~
출처