[JS] Promise (드림코딩 by 엘리)

0
post-thumbnail

🌼이 자료는 드림코딩 by 엘리님의 자바스크립트 12. 프로미스 개념부터 활용까지 JavaScript Promise | 프론트엔드 개발자 입문편 (JavaScript ES6) 강의를 정리한 내용입니다.


  • 자바스크립트는 동기적이다 -> 호이스팅(변수, 함수 선언이 상단으로 올라감)이 된 이후부터 코드가 내가 작성한 순서대로 동기적으로 실행이 된다.
  • Asyncronous한 동작 예시
  • 콜백도 비동기/동기 콜백으로 나누어 진다.
console.log('1');
setTimeout(function () {
  console.log('2');
},1000); //1초 뒤에 불러줘야하는 함수(콜백함수)
console.log('3'); 

//1 -> 3 -> 2 출력

콜백 지옥

콜백지옥 : 콜백함수 안에서 다른 콜백함수를 계속 부르는 코드

  • 가독성이 떨어짐
  • 디버깅 어려움
  • 유지보수 어려움

promise

  • promise는 자바스크립트 객체이다.
  • state, producer(정보 제공자)/consumer (정보 소비자) 차이 이해를 하는 것이 중요하다.
  • 비동기를 구현할 때 쓰이는 객체이다.
  • state: pending -> fulfilled / rejected
  • producer, consumer의 차이를 이해

1. producer

프로미스 만들기

const promise = new Promise(executor);

promise는 class이기 때문에 new 키워드를 통해 객체를 생성한다.promise는 executor이라는 callback 함수를 전달해줘야 하는데 이 callback 함수에는 또 다른 두 가지의 callback 함수를 받는다.

  • resolve 함수 : 기능을 정상적으로 수행해서 마지막에 최종 데이터를 전달함
  • reject 함수 : 기능을 수행하다가 중간에 문제가 생기면 호출한다.
const promise = new Promise((resolve, reject) => {
  //network 통신, read files 등의 haeavy work를 수행 
  console.log("doing something...");
  setTimeout(() => {
    resolve("ellie");
  }, 2000);
});
  • 코드에서 promise가 만들어지는 순간 excutor가 실행된다. 네트워크 통신을 수행하게 된다.
  • 만약 네트워크 요청을 사용자가 요구했을 때만 해야하는 경우라면 (e.g. 버튼을 눌렀을 때 네트워크 요청) 위 코드처럼 작성했을 때는 사용자가 요청하지 않았는데 불필요한 통신이 일어날 수 있다.
  • 프로미스가 생성된 순간 executor라는 callback 함수가 바로 실행되기 때문에 이 점에 유의하면서 코드를 작성해야 한다

2. Consumers : then, catch, finally로 데이터 가져오기

1) resolve - then

const promise = new Promise((resolve, reject) => {
  //network 통신, read files 등의 haeavy work를 수행 
  console.log("doing something...");
  setTimeout(() => {
    resolve("ellie"); // 성공 했을 시 
  }, 2000);
});
promise.then((value) => {
  console.log(value); 
})
  • 프로미스가 정상적으로 수행되어서 마지막으로 resolve라는 콜백함수를 통해 전달된 값이 value로 들어옴
  • resolve가 'ellie'라는 값을 전달하는 것!!

2) reject - catch

  • promise 내부에서 실행되는 일이 실패하였을 때는 reject를 호출함. 보통 error 오브젝트로 값을 전달함.
const promise = new Promise((resolve, reject) => {
  //network 통신, read files 등의 haeavy work를 수행 
  console.log("doing something...");
  setTimeout(() => {
    // resolve("ellie");
    reject(new Error("no network"));
  }, 2000);
});

위 코드를 reject로 변경 후 다시 실행하면 uncaught error가 발생함

promise.then(value => {
  console.log(value); 
})


catch를 사용해서 에러 발생시 어떻게 처리할 건지에 대한 콜백함수를 등록해주면 된다.

promise.catch(error => {
  console.log(error)
});

이렇게 작성하면 promise reject에서 받아온 값이 error로 들어옴
promise도 array method와 같이 chaining 형식으로 작성 가능

promise
  .then(value => {
  console.log(value); 
})
  .catch(error => {
  console.log(error);
})

3) finally

성공, 실패와 상관 없이 어떤 기능을 마지막으로 실행하고 싶을 때 finally 이용

promise
  .then(value => {
  console.log(value); 
})
  .catch(error => {
  console.log(error);
})
.finally(() => {
  console.log('finally');
})

3. Promise chaining

then은 값을 전달할 수도 있고 promise를 전달 할 수도 있음!!

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

fetchNumber
  .then(num => num * 2)
  .then(num => num * 3)
  .then(num => {
    return new Promise((resolve, reject) => {
      setTimeout(() => resolve(num - 1), 1000);
    });
})
.then(num => console.log(num));

4. Error Handling

const getHen = () => 
  new Promise((resolve, reject)=>{
    setTimeout(() => resolve('🐔'), 1000);
  });

const getEgg = hen => 
  new Promise((resolve, reject)=>{
    setTimeout(() => reject(new Error(`error! ${hen} =>🐵`)), 1000);
  });

const cook = egg => 
  new Promise((resolve, reject)=>{
    setTimeout(() => resolve(`${egg} => 🍳`), 1000);
  });

getHen()
  .then(getEgg)
  .then(cook) //then으로 전달 받은 value로 다른 함수를 호출할 때는 (egg => cook(egg)) 로 안 써도 됨
  .catch(console.log)
  .then(console.log)


참고

0개의 댓글