[JS] Promise

lyshine·2023년 4월 15일
0

스터디

목록 보기
3/7

Promise

Promise 상태 변화

  1. Pending (대기 상태) : 비동기 작업이 진행 중이거나, 실행될 수 없는 상태
  2. Fulfilled (성공) : 비동기 작업이 의도한대로 수행된 상태
  3. Rejected (실패) : 비동기 작업이 실패한 상태
  • Pending → Fulfilled : Resolve (성공)
  • Pending → Rejected: Reject (실패)
res.then(()=>{성공한 경우 콜백함수}).catch(()=>{실패한 경우 콜백함수})

Promise 활용 코드

function isPositiveP(number) {
	const executor = (resolve, reject) => {
		setTimeout(() => {
			if(typeof number === "number"){
				resolve(number >=0 ? "양수":"음수");
			}else{
				reject("주어진 값이 숫자형 값이 아닙니다.");
			}
		},2000);
	};

	const asyncTask = new Promise(executor);
	return asyncTask; //Promise를 반환
}

const res = isPositiveP(101);
//resolve, reject의 결과값을 사용 가능함

res
	.then((res)=>{console.log("작업 성공:", res)})
	.catch((err)=>{console.log("작업 실패:", err)})
//작업 성공: 양수
  • resolve를 수행했을때 전달한 결과값을 then 콜백함수에서 받아올 수 있고, reject를 수행했을때 전달한 결과값을 catch 콜백함수에서 받아올 수 있다.
  • Promise 사용시 콜백함수는 필요없다. resolve, reject를 활용하면 된다.
  • 어떤 함수가 Promise를 반환한다는 것은 이 함수는 비동기 작업을 하고 그 작업의 결과를 Promise 객체로 반환받아서 사용할 수 있는 함수로 볼 수 있다.

Promise로 콜백함수의 문제점 해결

  • 콜백함수 사용시 코드 (문제점 발생)
function taskA(a, b, cb) {
  // 지역변수를 사용할 수 있도록 콜백함수 선언
  setTimeout(() => {
    const res = a + b;
    cb(res); // 콜백함수 호출
  }, 3000); // 3초 뒤에 콜백함수 수행
}
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(4, 5, (a_res) => {
  console.log("A result: ", a_res);
  taskB(a_res, (b_res) => {
    console.log("B result: ", b_res);
    taskC(b_res, (c_res) => {
      console.log("C result: ", c_res);
    });
  });
});

console.log("코드 끝");

⇒ 가독성이 떨어지고 콜백이 깊어져 콜백 지옥이 발생한다.

  • Promise를 사용해 문제점 해결
function taskA(a, b) {
  const executerA = (resolve, reject) => {
    setTimeout(() => {
      const res = a + b;
      resolve(res);
    }, 3000); // 3초 뒤에 수행
  };
  return new Promise(executerA);
}
function taskB(a) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a * 2;
      resolve(res);
    }, 1000);
  });
}

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

taskA(5, 1) //taskA함수에서 반환하는 Promise 객체
  .then((a_res) => {
    console.log("A result: ", a_res);
		//반환해줘야함
    return taskB(a_res); // taskB를 호출하고 그 결과값을 반환
  })
	//taskB()의 리턴인 Promise객체의 then 함수
  .then((b_res) => {
    console.log("B result: ", b_res);
    return taskC(b_res);
  })
  .then((c_res) => {
    console.log("C result: ", c_res);
  });

/** 함수를 부분분리 할 수도 있다. **/
// taskA 호출
const aPromise = taskA(5, 1).then((a_res) => {
  console.log("A result: ", a_res);
  return taskB(a_res); // taskB를 호출하고 그 결과값을 반환
});

//다른 작업
console.log("----");
console.log("----");

aPromise
  .then((b_res) => {
    console.log("B result: ", b_res);
    return taskC(b_res);
  })
  .then((c_res) => {
    console.log("C result: ", c_res);
  });

//----
//----
//A result: 6
//B result: 12
//C result: -12

⇒ 콜백지옥 해결, 좀 더 가독성 좋고 깔끔한 코드 작성 가능

0개의 댓글