[JavaScript] 자바스크립트 Promise

S0ju·2022년 6월 30일
0

JavaScript

목록 보기
20/22

콜백지옥을 구원하기 위한 자바스크립트의 비동기 담당 객체 : promise


<비동기 작업이 가질 수 있는 3가지 상태>

  • Pending(대기 상태) : 현재 비동기 작업이 진행중이거나 이 작업이 시작할 수도 없는 문제가 발생했음을 의미
  • Fulfilled(성공) : 비동기 작업이 의도한대로 정상적으로 완료됨을 의미
  • Rejected(실패) : 비동기 작업이 모종의 이유로 실패했음을 의미 (서버의 무응답 or 시간초과로 인한 자동취소 등)

-> 비동기 작업은 한 번 작업이 성공하거나 실패하면 그걸로 끝

Pending -> Fulfilled : resolve(해결)

Pending -> Rejected : reject(거부)


2초 뒤에 전달받은 값이 양수인지 음수인지 판단하는 비동기 작업👇

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);
  }
);
// 성공적으로 수행됨 : 양수
function isPositive(number,resolve,reject){
  setTimeout(()=>{
    if(typeof number === "number"){
      //성공 -> resolve
      resolve(number >= 0 ? "양수" : "음수");
    }else{
      //실패 -> reject
      reject("주어진 값이 숫자형 값이 아닙니다");
    }
  },2000);
}

isPositive(
  [],
  (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;
}

isPositiveP(101);
//101

isPositiveP 함수의 반환값이 Promise로 바뀌어 있음
어떤 함수가 Promise를 반환한다는 것은 이 함수는 비동기 작업을 하고 그 작업의 결과를 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(101);

res
  .then((res)=>{ //resolve 수행시 결과값
  console.log("작업 성공 : ",res);
})
  .catch((err)=>{ //reject 수행시 결과값
  console.log("작업 실패 : ",err);
});
//작업 성공 : 양수

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([]);

res
  .then((res)=>{ //resolve 수행시 결과값
  console.log("작업 성공 : ",res);
})
  .catch((err)=>{ //reject 수행시 결과값
  console.log("작업 실패 : ",err);
});
//작업 실패 : 주어진 값이 숫자형 값이 아닙니다

지난번 콜백함수👇

function taskA(a,b,cb){//콜백이라는 의미의 cb
  setTimeout(()=>{
    const res = a+b; //지역 상수
    cb(res);
  },3000);
}

function taskB(a,cb){//콜백이라는 의미의 cb
  setTimeout(()=>{
    const res = a*2; //지역 상수
    cb(res);
  },1000);
}

function taskC(a,cb){//콜백이라는 의미의 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);
    });
  });
});

// task A : 7
// task B : 14
// task C : -14

콜백지옥을 해결하기 위해 promise를 써보자

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

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)
  .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);
});
// 이렇게 then 메소드를 계속 이어서 붙이는 것을 then chaining이라고 부름

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

/*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);
    });
  });
});*/ //콜백식

이렇게 promise를 반환하는 함수로 바꾼 이유는 어떤 함수가 promise 객체를 반환한다는 건 그 함수는 비동기적으로 동작하고 반환한 promise 객체를 이용해서 비동기 처리의 결과값을 then과 catch로 이용할 수 있게 만들겠다는 의미

promise 객체를 이용하면 중간에 다른 작업을 넣을 수도 있음

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

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);
  });
}

const bPromiseResult = taskA(5,1)
  .then((a_res) => {
  console.log("A RESULT : ",a_res);
  return taskB(a_res);
});

console.log("dhfkjsdnfsdnfkd");
console.log("dhfkjsdnfsdnfkd");
console.log("dhfkjsdnfsdnfkd");
console.log("dhfkjsdnfsdnfkd");
console.log("dhfkjsdnfsdnfkd");

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

// dhfkjsdnfsdnfkd 다섯번
// A RESULT : 6
// B RESULT : 12
// C RESULT : -12

이렇게 promise 객체를 이용하면 이 비동기 처리를 호출하는 코드와 결과를 처리하는 코드를 분리해줄 수 있어서 콜백함수를 피하고 좀 더 가독성 있고, 깔끔한 비동기처리를 할 수 있도록 도와준다.

profile
프론트엔드 개발자가 되기 위해 공부중입니다 : )

0개의 댓글

관련 채용 정보