JS/etc

JavaScript Engine - 5. 비동기 시작(callback, promise)

mnmhbbb 2022. 3. 23. 00:02

2-1 프로미스의 최고 장점을 아십니까

https://youtu.be/0f-jNhnN0Qc

"프로미스는 결과값을 나중에 쓸 수 있다"

 

call back

setTimeout(() => {
  console.log('a');
}, 1000);
  • 위 코드는 1초만 지나면 () => {console.log('a');}가 반드시 즉시 실행됨
    (코드 분리 불가능. 강제적으로 즉시 실행)
  • 콜백함수의 단점
    • 결과값을 바로 받아야 한다.
    • 코드 가독성이 떨어진다.
  • 콜백이라고 꼭 비동기가 아니다. 비동기콜백/동기콜백
  • 비동기콜백의 대표적인 것 setTimeout

 

Promise

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve();
  }, 1000);
});

// code ...

promise.then((결괏값) => {
  // 결괏값 사용...
  console.log('a');
});
  • 프로미스를 실행하고, promise라는 변수에 결과값을 담아놓고 있다가 필요한 순간에 가져와서 사용할 수 있다.
  • 실행하고 그 결과값을 나중에 쓸 수 있는 것(코드 분리)
  • 코드를 분리할 수 있다는 강력한 장점
  • Promise() 안에 있는 함수는 동기 함수(즉시 실행됨)
new Promise((resolve, reject) => {
  // 여기 작성한 코드는 바로 실행됨(동기)
  console.log(1);
});
console.log(2);
// 1 2
  • resolve에 담아놓은 결괏값을 나중에 then으로 받아서 사용할 수 있는 것
const p1 = axios.get('서버주소1');
const p2 = axios.get('서버주소2');
const p3 = axios.get('서버주소3');
const p4 = axios.get('서버주소4');
const p5 = axios.get('서버주소5');

Promise.all([p1, p2, p3, p4, p5])
  .then((results) => {})
  .catch((error) => {})
  .finally(() => {});
  • p1에다가 axios 요청 보내놓고, 다른 작업하다가 한 번에 결과값 받아오는 코드
  • 단, 이 코드(all)의 단점은 하나라도 실패하면 catch가 실행된다는 것
  • 그래서 이러한 점을 보완하는 allSettled()
  • (ES2020 추가됨)
  • 그래서 all 안씀
Promise.allSettled([p1, p2, p3, p4, p5])
  .then((results) => {})
  .catch((error) => {})
  .finally(() => {});
  • 예를 들어 p2가 실패했다. 성공한 값은 result로 실패한 값은 catch로
  • 성공/실패 상관없이 무조건 결과값을 담아주기 때문에 실패한 것만 필터링해서 다시 시도할 수 있다.
  • 참고로 .catch()는 catch 바로 앞에 있는 값에 대한 catch이다. 이 경우는, promise.then()에 대한 catch
  • try{} catch (err) {} finally {}로 작성할 수도 있다.

 

promise -> async/await으로 바꾸기

  • async/await도 자체도 promise이다.
  • 무지성 async/await으로 교체하면 안된다.
  • async/await을 쓰더라도 promise를 써야 하는 경우가 있다.
  • (뒤에 있는 강의에서 설명 예정)