Cs

24. javascript - Promise (feat.콜백지옥)

ITSEONG 2022. 5. 26. 00:24

promise는 비동기 작업의 완료 또는 실패를 나타내는 객체이다. 

 

promise의 상태는 3가지이다.

 

1. 대기(pending) : 이행하지도 거부하지도 않은 초기 상태.

2. 이행(fulfilled) : 연산이 성공적으로 완료됨.

3. 거부(rejected) : 연산이 실패함.

const pr = new Promise((resolve, reject) => {
    //수행한 작업이 성공한 경우 resolve(...)를 호출하고, 실패한 경우 reject(...)를 호출합니다.
    setTimeout(()=>{
     resolve('Ok')
    }, 3000)
})

promise는 값과 함께 이행되거나 오류로 인해 거부될 수 있다. 그땐 then 메서드에 의해 처리된 값들을 호출할 수 있다.

pr.then(
    function(result){} //이행되었을때 실햄됨
    function(err){}    //거부되었을때 실햄됨
)

catch 메서드를 이용하여 거부되었을 때 메서드를 따로 호출할 수 있다. 아래와 같이 나타낼 수 있다.

 console.log('시작');
pr.then((result) => { //이행되었을때
 console.log(result);
})
.catch((err)=>{ //거부되었을때
 console.log(err)
})
.finally(()=>{ //프로미스 처리가 되었을때
 console.log('끝');
})

promise가 나오기 이전에 콜백 함수를 호출하는 함수를 살펴보자. 예를 들어 f1을 호출할 때 f2를 호출하며 f3도 같이 호출을 한다고 하자.

함수를 1개씩 호출할 때 마다 depth가 깊어지는 것을 볼 수 있다. 이를 콜백 헬, 콜백 지옥이라고 부른다...

const f1 = (callback)=>{
  console.log('1번째');
  callback();
}

const f2 = (callback)=>{
  console.log('2번째');
  callback();
}
const f3 = (callback)=>{
  console.log('3번쨰');
  callback();
}

console.log('시작');
f1(function(){
  f2(function(){
    f3(function(){
      console.log('끝');
    });
  });
});

이런 콜백 지옥은 프로미스 함수를 이용하여 처리할 수 있다. 

const f1 = () =>{
  return new Promise((res, rej)=>{
    setTimeout(()=>{
      res("1번째")
    }, 3000);
  });
}

const f2 = (message) => {
  console.log(message);
  return new Promise((res, rej) => {
    setTimeout(()=>{
      res('2번째')
    },1000);
  })
}

const f3 = (message) => {
  console.log(message);
  return new Promise((res, rej) => {
    setTimeout(()=>{
      res('3번째')
    },2000);
  })
}

프로미스를 사용하면 1 depth로 처리할 수 있는 것을 볼 수 있다.

f1().then(
 (res) => f2(res)
).then(
 (res) => f3(res)
).then(
 (res) => console.log(res)
).catch(
 console.log('err')
).finally(()=>{
  console.log('끝')
})

promise는 순차적으로 처리하지 않고 모든 작업을 한 번에 처리할 수 있다. promise.all을 이용하는 것이다.

let pr = Promise.all([f1(),f2(),f3()]).then((res) => console.log(res));

위와 같이 f1,f2,f3라는 함수가 있으면 동시에 실행되고 함수가 모두 실행 완료된 시점에서 프로미스는 종료된다.

 

promise는 한 번만 실행된다. 프로미스로 생성된 비동기 인스턴스는 한 번만 실행된다.

let pr = Promise.resolve(Math.random());

pr.then((res)=>{
	console.log(res);
})

pr.then((res)=>{
	console.log(res);
})

pr.then((res)=>{
	console.log(res);
})
// 세 가지 모두 같은 값

한 번 생성된 promise인스턴스에 아무리 then을 날려도 이미 결정된 promise는 같은 결과를 보여준다는 뜻이다.

 

정리 Promise의 특징

1. ES6부터 정식으로 명시된 비동기 처리 api

2. 한 번만 실행되는 특징

3. 기존 비동기 형태에서 발생하는 콜백 지옥을 개선할 수 있도록 표준화한다.

반응형