Promise

이윤택·2021년 6월 16일
0

Asynchronous & Promise

목록 보기
2/2

유튜브 동영상이 로딩되는 동안, 댓글을 달지 못하거나, 검색을 하지 못하는 등, 요청이 동기적으로 이루어진다면 매우 불편할 것이다. 갑자기 다른 동영상을 보고싶어 클릭을 해도 지금 영상이 완전히 로딩되지 않는다면 넘어갈 수 없기 때문이다. 하지만 단순한 비동기 처리는, 호출에 대한 처리가 랜덤으로 되는 일이 발생한다. 각 처리마다 걸리는 시간이 다르기 때문이다. 비동기에 대한 순서를 제어하는 방법들을 소개하겠다.

1. Callback(콜백)

function printString(string){
	setTimeout(() => {
		console.log(string)
	},
	Math.floor(Math.random() * 100) + 1
}

function printAll() {
	printString('a')
	printString('b')
	printString('c')
}

위 코드의 경우, setTimeout의 파라미터가 랜덤으로 들어가기 때문에, 각 알파벳이 순서대로 출력되지 않는다.

function printString(string, callback){
	setTimeout(() => {
		console.log(string)
		callback()
	},
	Math.floor(Math.random() * 100) + 1
}

function printAll() {
	printString('a', () => {
		printString('b', () => {
			printString('c', () => ())
		})
	})
}

위 코드의 경우, 인자에 콜백을 넣어 a를 출력하고 난 다음 printString('b')를 실행하기 때문에 a를 출력하는 데에 얼마나 걸리든 원하는 순서대로 출력을 낼 수 있다. 하지만 더 많은 함수를 순차적으로 실행시켜야 하는 경우 아래 그림과 같이 콜백지옥에 빠질 수 있다.
출처: https://adrianalonso.es/desarrollo-web/apis/trabajando-con-promises-pagination-promise-chain/

2. Promise(프로미스)

프로미스를 이용하여 위에서 본 콜백지옥에서 탈출할 수 있다. 프로미스 기반 비동기 함수를 호출하면, 해당 비동기 함수는 프로미스 객체를 반환한다. 프로미스 객체는 총 3가지 상태를 가지고 있다.

  • Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태(초기 상태)
  • Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태(연산 성공)
  • Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태(연산 실패)

프로미스 생성

: 프로미스 인스턴스를 만만들어 resolve와 reject 콜백이 있는 콜백 함수를 인자로 넣어준다.

const printString = (string) => {
    return new Promise((resolve, reject) => {
      setTimeout(
        () => {
         console.log(string)
         resolve()
        }, 
       Math.floor(Math.random() * 100) + 1
      )
    })
  }
 
  const printAll = () => {	
    printString("A")
    .then(() => {			//생성한 promise 사용
      return printString("B")
    })
    .then(() => {
      return printString("C")
    })
  }
  printAll()

3. Async & Await

콜백 지옥을 빠져나오기 위해 사용하는 프로미스 또한, 반복이 되면 콜백 지옥과 같은 구조가 될 가능성이 있다. then 실행절에서 새로운 프로미스를 만들거나, then절이 길어진다면 콜백 지옥과 다를 것이 없다. 이 문제를 해결하기 위해 Async,Await가 등장했다.

function makeCoffee(order){
  return new Promise((resolve, reject)=>{
    setTimeout(()=>{
      let coffee = `make ${order}`;
      console.log(coffee);
      resolve(coffee);
    }, 
    Math.floor(Math.random() * 100) + 1) // 임의의 값 생성
  }); 
}

async function asyncGetCoffee(){
  // 동기적으로 실행결과를 얻을 수 있다.
  let americano = await makeCoffee('아메리카노');
  let vanillaLatte = await makeCoffee('바닐라 라떼');
  let einspanner = await makeCoffee('아인슈페너');
}

asyncGetCoffee(); 

AwaitAsync 함수 안에서만 사용할 수 있다.

에러 처리

Async & Await에서 에러를 처리하는 방법은 크게 두 가지가 있다.

  • try ~ catch
  • .catch() 블럭
profile
데이터 엔지니어로 전향중인 백엔드 개발자입니다

0개의 댓글