동기 vs 비동기 (2)

kirin.log·2021년 3월 7일
2
post-custom-banner

🎃 Promise

  • 자바스크립트 비동기 처리에 사용되는 객체
  • 주로 서버(server)에서 받아온 데이터를 화면에 표시할 때 사용
    ❗ API가 실행되면 서버에다가 ‘데이터 하나 보내줘’ 라는 요청을 보내지만, 여기서 데이터를 받아오기도 전에 마치 데이터를 다 받아온 것 마냥 화면에 데이터를 표시하려고 하면 오류가 발생하거나 빈 화면이 뜬다.
    이와 같은 문제점을 해결하기 위한 방법 중 하나가 프로미스 이다.
    비동기에서 성공과 실패를 분리해서 메서드를 수행한다.

🐥 프로미스의 3가지 상태(states)

  • 상태(state)란 프로미스의 처리 과정을 의미

  • new Promise()로 프로미스를 생성하고 종료될 때까지 3가지 상태를 갖는다

  • state : PendingFulfilled or Rejected

    • Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
    • Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
    • Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태
  • Producer(promise object) vs Consumer
    (promise 객체 생성하는 입장 / 생성된 데이터를 소비하는 입장)


🐣 Producer 만들기 (=Promise Object 만들기)

🪐 Pending(대기)

  • new Promise() 메서드를 호출하면 대기(Pending) 상태
const promise = new Promise();
  • new Promise() 메서드를 호출할 때 콜백 함수를 선언할 수 있고, 콜백 함수의 인자는 resolve, reject 이다.
    ❗ Promise가 생성되면, 해당 함수 안의 실행코드가 자동적으로 바로 실행된다
const promise = new Promise (function (resolve, reject) {
	// 콜백함수 내 로직 automatically 바로 실행
 });

🪐 Fulfilled(이행, =완료)

  • 콜백 함수의 인자 resolve를 아래와 같이 실행하면 이행(Fulfilled) 상태가 된다
// 예시 1)
const promise = new Promise (function (resolve, reject) {
  resolve();
});


// 예시 2)
// setTimeout() 함수를 통해 resolve() 이행하기

const promise = new Promise (function (resolve, reject) {
  setTimeout(() => {
     resolve("네트워크에서 성공적으로 받아온 데이터를 resolve 콜백함수로 받아와서 호출");
}, 2000);

🐣 Consumer 만들기 (= 값 받아오기)

🪐 then(성공한 값), catch(실패한 값), finally(성공이든 실패든 호출) 활용하기

  • 이행 상태(Fulfilled)가 되면 아래와 같이 then()을 이용하여 처리 결과 값을 받을 수 있다.
// 예시 1)
function getData() {
  return new Promise (function (resolve, reject) {
    let data = 100;
    resolve(data);
  });
}

// resolve()의 결과 값 data를 resolvedData로 받음
getData().then( function (resolvedData) {
	console.log(resolvedData);     // 100
});


// 예시 2)
const promise = new Promise((resolve, reject) => {
	console.log('doing something...');
    setTimeout(() => {
    	resolve('결과값');
    }, 2000);
});

promise.then(value => {
	console.log(value)             // '결과값'
});
// promise가 정상적으로 수행이 되어서, resolve()라는 콜백함수의 전달한 값이 
// .then의 value라는 파라미터로 전달되어 출력됨

🪐 Rejected(실패)

  • new Promise()로 프로미스 객체를 생성하면 콜백 함수 인자로 resolvereject를 사용할 수 있는데, 여기서 reject를 아래와 같이 호출하면 실패(Rejected) 상태가 된다
new Promise( function (resolve, reject) {
  reject();
});
  • 실패 상태(Rejected)가 되면 실패한 이유(실패 처리의 결과 값)를 catch()로 받을 수 있다.
// 예시 1)
function getData() {
  return new Promise( function (resolve, reject) {
    reject( new Error ("Request is failed") );
  });
}

// reject()의 결과 값 Error를 err에 받음
getData().then().catch( function(err) {
  console.log(err);         // Error: Request is failed
});


// 예시 2)
const promise = new Promise((resolve, reject) => {
	console.log('doing something...');
    setTimeout(() => {
    	reject(new Error('no network');
    }, 2000);
});

promise.then.catch(error => {
	console.log(error)             // '결과값'
});
  • 성공 상태(resolve) 이든 실패 상태(Rejected) 이든 결과값을 호출 (인자를 받지 않는다)
// 예시 1)  ---  reject의 경우
const promise = new Promise((resolve, reject) => {
	console.log('doing something...');
    setTimeout(() => {
    	reject(new Error('no network');
    }, 2000);
});

promise
	.then(value => {
    	console.log(value)            
    })
    .catch(error => {
		console.log(error)             // '결과값'
    })
    .finally(() => {
    	console.log('finally')        // finally
});
// 출력결과:
// 결과값
// finally


🥇 Promise Chaining

// 1초 뒤에 숫자 1을 전달하는 promise 생성
const fetchNumber = new Promise((resolve, reject) => {
	setTimeout( () => resolve(1), 1000);
});

// fetchNumber를 성공적으로 받아오면 (.then)
fetchNumber
.then(num => num * 2)  // 1에 2를 곱한 값을 출력, 2
.then(num => num * 3)  // 2에 3을 곱한 값을 출력, 6
.then(num => {
	return new Promise((resolve, reject) => {
    	setTimeout( () => resolve(num-1), 1000);
                       // 6에 1을 뺀 값을 출력, 5
    });
})
.then(num => console.log(num));  // 결과적으로 num은 5가 출력
// 1초 뒤에 '닭'을 출력하는 promise 생성
const getHen = () => {
	new Promise((resolve, reject) => {
    	setTimeout( () => resolve('🐔'), 1000);
   });

// hen에서 'egg'를 출력해서 1초 뒤에 출력하는 promise 생성
const getEgg = hen => {
	new Promise((resolve, reject) => {
    	setTimeout( () => resolve(`${hen} => 🥚`), 1000);
   });

// egg에서 '후라이'를 출력해서 1초 뒤에 출력하는 promise 생성
const cook = egg => {
	new Promise((resolve, reject) => {
    	setTimeout( () => resolve(`${egg} => 🍳`), 1000);
   });



getHen()
.then(hen => getEgg(hen))
.then(egg => cook(egg))
.then(meal => console.log(meal))


// 출력결과: (3초 뒤에 출력)
// 🐔 => 🥚 => 🍳
profile
boma91@gmail.com
post-custom-banner

0개의 댓글