Web/JavaScript

JavaScript 응용 #4 Promise - 콜백 지옥에서 탈출하기

ansui 2023. 9. 16. 22:31

#8 Promise - 콜백 지옥에서 탈출하기

 
< 비동기 작업이 가질 수 있는 3가지 상태 >
Pending (대기 상태): 현재 비동기 작업이 진행 중이거나 작업이 시작할 수 없는 문제가 발생한 경우
해결 (resolve) → Fulfilled (성공): 비동기 작업이 의도한 대로 작업된 상태
거부 (reject) → Rejected (실패): 비동기 작업이 실패한 경우
*Promise는 만들어지면 자동적으로 실행
 
< 콜백 이용 >

function isPositive(number, resolve, reject) {
  setTimeout(() => {
    if(typeof number === 'number') {
      //성공 -> resolve
      resolve(number >= 0 ? "양수" : "음수")
    } else {
     //실패 -> reject
     reject("주어진 값이 숫자형 값이 아닙니다.")
    }
  }, 2000);
}

isPositive(10, (res) => {
  console.log("성공: ", res);
}, (err) => {
  console.log("실패: ", err);
  }
);
//성공: 양수

 
< Promise 이용 >

function isPositiveP(number) {
  const executor = (resolve, reject) => { //실행자
    setTimeout(() => {
      if(typeof number === 'number') {
        //성공 -> resolve
        console.log(number);
        resolve(number >= 0 ? "양수" : "음수");
      } else {
       //실패 -> reject
       reject("주어진 값이 숫자형 값이 아닙니다.");
      }
    }, 2000);
  };
  const asyncTask = new Promise(executor);
  return asyncTask;
}

const res = isPositiveP(10);

res.then((res) => {
  console.log("작업 성공: ", res);
  }).catch((err) => {
    console.log("작업 실패: ", err);
  });

return asyncTask;를 추가하면 Promise <any>로 변경됨!

출력 결과

 
< 콜백 헬 예시 >

function taskA(a, b, cb) {
  setTimeout(() => {
    const res = a + b;
    cb(res);
  }, 3000)
}

function taskB(a, cb) {
  setTimeout(() => {
    const res = a * 2;
    cb(res);
  }, 1000)
}

function taskC(a, cb) {
  setTimeout(() => {
    const res = a * -1;
    cb(res);
  }, 2000)
}

taskA(3, 4, (a_res) => {
  console.log("task_A : ", a_res);
  taskB(a_res, (b_res) => {
    console.log("task_B : ", b_res);
    taskC(b_res, (c_res) => {
      console.log("task_C : ", c_res);
    })
  })
})
출력 결과

 
< Promise로 해결 >

function taskA(a, b) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a + b;
      resolve(res);
    }, 3000);
  })
}

function taskB(a, cb) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a * 2;
      resolve(res);
    }, 1000);
  })
}
  
function taskC(a, cb) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a * -1;
      resolve(res);
    }, 2000);
  })
}

taskA(5, 1).then((a_res) => {
  console.log("A RESULT: ", a_res);
  taskB(a_res).then((b_res) => {
    console.log("B RESULT: ", b_res);
    taskC(b_res).then((c_res) => {
      console.log("C RESULT: ", c_res);
    });
  });
});

< then chaining >

taskA(5, 1).then((a_res) => {
  console.log("A RESULT: ", a_res);
  return taskB(a_res);
}).then((b_res) => {
  console.log("B RESULT: ", b_res);
  return taskC(b_res);
}).then((c_res) => {
  console.log("C RESULT: ", c_res);
})
출력 결과

 


이정환님의 인프런 강의 "한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지"를 참고하여 작성하였습니다.