반응형

Promise

자바스크립트에서 Promise API는 비동기 API이다.

따라서 setTimeout은 Task queue에 저장되는 것과 달리, Promise API는 Job queue에 저장된다.

job que가 task que보다 우선순위 높기 때문에 아래와 같은 결과가 나온다.

setTimeout(() => {
	consoloe.log("타임 아웃1")
}, 0);

Promise.resolve().then( () => console.log("프로미스1"));

setTimeout(() => {
	consoloe.log("타임 아웃2")
}, 0);

Promise.resolve().then( () => console.log("프로미스2"));


// 출력
// 프로미스1 프로미스2
// 타임 아웃1 타임 아웃2

 

 


 

Promise의 작업 상태

new Promise( )로 프로미스를 생성하고 종료 될 때까지 3가지 상태를 갖는다.

 

(1) Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태

new Promise() 메서드를 호출하면 대기(Pending) 상태가 된다. 이때 콜백 함수를 선언할 수 있고, 콜백 함수의 인자는 resolve, reject다.

new Promise(function(resolve, reject) {
  // ...
});

 

(2) Fulfilled(이행 == 완료) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태

여기서 콜백 함수의 인자 resolve를 아래와 같이 실행하면 이행(Fulfilled) 상태가 된다.

new Promise(function(resolve, reject) {
  resolve();
});

이행 상태가 되면 아래와 같이 then()을 이용하여 처리 결과 값을 받을 수 있다.

function getData() {
  return new Promise(function(resolve, reject) {
    var data = 100;
    resolve(data);
  });
}

// resolve()의 결과 값 data를 resolvedData로 받음
getData().then(function(resolvedData) {
  console.log(resolvedData); // 100
});

 

(3) Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태

reject를 아래와 같이 호출하면 실패(Rejected) 상태가 된다.

new Promise(function(resolve, reject) {
  reject();
});

실패 상태가 되면 실패한 이유(실패 처리의 결과 값)를 catch()로 받을 수 있다. (reject보다는 catch를 추천함)

function getData() {
  return new Promise(function(resolve, reject) {
    reject(new Error("Request is failed"));
  });
}

// reject()의 결과 값 Error를 err에 받음
getData().then().catch(function(err) {
  console.log(err); // Error: Request is failed
});

 

 

Promise.resolve와 Promise.reject

Promise.resolve함수는 Promise를 바로 반환한다.
Promise.reject함수는 실패한 Promise를 바로 반환한다.

Promise
    .resolve(10)
    .then(console.log)

Promise
    .reject("Error")
    .catch(console.log)

 

 

Promise로 then, catch, finally 코드

then ( ) 메서드: 성공했을 때, 실행할 콜백함수를 인자로 넘긴다.

catch ( ) 메서드: 실패했을 때, 실행할 콜백함수를 인자로 넘긴다.

finally ( ) 메서드: 성공/실패 여부와 상관없이 모두 실행할 콜백 함수를 인자로 넘긴다.

function getData() {
  return new Promise(function(resolve, reject) {
    $.get('url 주소/products/1', function(response) {
      if (response) {
        resolve(response);
      }
      reject(new Error("Request is failed"));
    });
  });
}

// 위 $.get() 호출 결과에 따라 'response' 또는 'Error' 출력
getData().then(function(data) {
  console.log(data); // response 값 출력
}).catch(function(err) {
  console.error(err); // Error 출력
}).finally(function() {
  console.log("promise 종료"); // 성공/실패 여부에 관계없이 항상 실행
});

 

 

 

Promise Chaning ( 여러 개의 프로미스 연결하기)

then() 메서드를 호출하고 나면 새로운 프로미스 객체가 반환된다. 따라서, 아래처럼 체인 형식으로 구현이 가능해진다.

 

new Promise(function(resolve, reject){
  setTimeout(function() {
    resolve(1);
  }, 2000);
})
.then(function(result) {
  console.log(result); // 1
  return result + 10;
})
.then(function(result) {
  console.log(result); // 11
  return result + 20;
})
.then(function(result) {
  console.log(result); // 31
});

프로미스 객체를 하나 생성하고 setTimeout()을 이용해 2초 후에 resolve()를 호출하는 예제

resolve()가 호출되면 프로미스가 대기 상태에서 이행 상태로 넘어가기 때문에 첫 번째 .then()의 로직으로 넘어감.

첫 번째 .then()에서는 이행된 결과 값 1을 받아서 10을 더한 후 그다음 .then() 으로 넘겨줌.

두 번째 .then()에서도 마찬가지로 바로 이전 프로미스의 결과 값 11을 받아서 20을 더하고 다음 .then()으로 넘겨줌.

마지막 .then()에서 최종 결과 값 31을 출력.

 

 

 

Promise.all

Promise 배열을 받아 모두 성공시 각 Promise의 resolved 값을 배열로 반환한다.

하나의 promise라도 실패할 시, 가장 먼저 실패한 promise의 실패 이유를 반환한다.

Promise.all([
    promise1,
    promise2,
    promise3
])
    .then(values => {
        console.log("모두 성공", values)
    })
    .catch(e => {
        console.log("하나라도 실패", e)
    })

 

 

 

 

 

 

 

반응형

+ Recent posts