[JS] Promise & Async/Await

Ericamoyed·2021년 6월 8일
0

개발한장

목록 보기
5/22

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
  • 볼드 처리해둔게 가능하게 하려면
      1. function 앞에 async 키워드로, 요 function 내부에서 비동기 call이 일어난다는걸 명시해줘야함.
      1. 실제 비동기 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) {} 하면 됩니다~

출처

profile
꿈많은 개발자, 일상 기록을 곁들인

0개의 댓글