COCO World

[Javascript/자바스크립트] Day5 - 프라미스(Promise)와 체이닝(chaining), 프라미스 API 본문

Language/JavaScript

[Javascript/자바스크립트] Day5 - 프라미스(Promise)와 체이닝(chaining), 프라미스 API

코코월드주인장 2023. 1. 26. 17:51

1. 프라미스(Promise)

   :자바스크립트 안에 내장되어있는 오브젝트. 비동기 처리를 위해 쓰이며, 콜백함수 대신에 쓸 수 있다.

 1.State
   : pending -> operation이 수행중일 경우, fulfilled : operation을 완료하였을 때, rejected : 수행을 완료하지 못했을때
 2. Producer : 원하는 기능을 수행해서 원하는 데이터를 만들어내는 역할
 3. Consumer : 원하는 데이터를 소모하는 역할

[1] Promise의 문법

   : new Promise에 전달되는 함수는 executor(실행자, 실행함수)라고 한다. 그 안의 인수  resolve,reject는 자바스크립트에서

   자체 제공하는 콜백이다.

  • resovle(value) : 일이 성공적으로 끝난 경우 그 결과를 나타내는 value와 함께 호출
  • reject(error) : 에러 발생 시 에러 객체를 나타내는 error와 함께 호출
let promise = new Promise(function(resolve, reject) {
   // executor(consumer, producer)
})

[2] Producer

   : executor는 resolve나 reject 중 하나를 반드시 호출해야 한다. 이때 변경된 상태는 더 이상 변하지 않는다.

  • resolve 한 경우 = fulfilled promise
let promise = new Promise((resolve, reject) => {
	// promise 생성시 executor함수는 자동 실행
    
    setTimeout(() => resolve("완료"), 1000);
});
  • reject 한 경우 = settled promise
let promise = new Promise((resolve, reject) => {
	// promise 생성시 executor함수는 자동 실행
    
    setTimeout(() => reject(new Error("에러 발생!")),1000);
});

[3] Consumer

   : consumer의 메서드로는 .then, .catch, .finally 메서드가 있으며, 이를 통해 등록한다.

 

  • .then의 사용(1) 
let promise = new Promise((resolve, reject) => {
    
    setTimeout(() => resolve("완료"), 1000);
});

// resolve함수가 실행 되기에 .then의 첫 번째 함수를 실행
promise.then(
   result => alert(result),	// 1초 후 '완료' 출력
   error => alert(error)	// 실행되지 않음
)
  • .then의 사용(2)
let promise = new Promise((resolve, reject) => {
    
    setTimeout(() => reject(new Error("에러")), 1000);
});

// reject함수가 실행 되기에 .then의 두 번째 함수를 실행
promise.then(
   result => alert(result),	// 실행되지 않음
   error => alert(error)	// 1초 후 'Errpr: 에러'을 출력
)
  • catch의 사용

    : 에러가 발생한 경우만 다루고 싶다면, .then(null, errorHandlingFunction)같이 null을 첫 번째 인수로 전달하면 된다.

       .catch(errorHandlingFunction) 를 써도 되는데, .catch는 .then에 null을 전달하는 것과 동일하다

let promise = new Promise((resolve, reject) => {
    
    setTimeout(() => reject(new Error("에러")), 1000);
});

// .catch는 promise.then(null, function)과 동일한 의미
promise.catch(alert);	// 1초 뒤 'Error : 에러' 출력
  • finally의 사용

    : 성공, 실패 여부와 상관없이 프라미스가 처리되면 실행된다

    : 다만 finally에는 인수가 없어서 프라미스가 성공인지 실패인지 알 수 없다. 여기에선 절차를 마무리하는 '보편적' 수행 역할을 함

let promise = new Promise((resolve, reject) => {
    
    setTimeout(() => resolve("완료"), 1000);
});

// resolve함수가 실행 되기에 .then의 첫 번째 함수를 실행
// finally 또한 출력
promise
   .then(
      result => alert(result),	// 1초 후 '완료' 출력
      error => alert(error)	// 실행되지 않음
   )
   .finally(() =>
      alert("프라미스 준비완료!")
   )

 

2. 프라미스 체이닝(Promise Chaining)

   : result가 .then 핸들러의 체인을 통해 전달된다는 점에서 착한한 아이디어이다.

   프라미스 체이닝이 가능한 이유는 Promise.then을 호출하면 프라미스가 반환되기 때문이다. 반환된 프라미스엔

   당연히 .then을 호출할 수 있다. 반환할 때엔 그 값이 프라미스의 result가 되고, 다음 .then 호출에 인자로써 사용된다.

 

  • 다만 프라미스 하나에 .then을 여러 개 추가하는 것이 체이닝이 아니니 헷갈리지 말자.
new Promise(function(resolve, reject){
   setTimeout(() => resolve(1), 1000);
   
}).then(function(result) {
    alert(result);
    return result * 2;
    
}).then(function(result) {
   alert(result);
   return result * 2;
   
}).then(function(result) {
   alert(result);
   return result * 2;
});

 

3.  프라미스 API

[1] Promise.all

    : 모든 프라미스가 이행될 때까지 기다렸다가 그 결괏값을 담은 배열을 반환한다. 주어진 프라미스 중 하나라도 실패하면

      Promise.all은 거부되고, 나머지 프라미스의 결과는 무시된다.

let names = ['iliakan', 'Violet-Bora-Lee', 'jeresing'];

let requests = names.map(name => fetch(`https://api.github.com/users/${name}`));

Promise.all(requests)
   .then(responses => {
   //모든 응답이 성공적으로 이행
   for (let response of responses) {
      alert(`${response.url}: ${response.statius}`);
   }
   return responses;
   })
   // 응답 메세지가 담긴 배열을 response.json()으로 매핑해 내용을 읽는다
   .then(responses => Promise.all(responses.map(r => r.json())))
   // JSON 형태의 응답 메세지는 파싱 되어 배열 users에 저장된다
   .then(users => users.forEach(user => alert(user.name)));

[2] Promise.allSettled

    : 최근에 추가된 메서드로 모든 프라미스가 처리될 때까지 기다렸다가 그 결과(객체)를 담은 배열을 반환한다

  • 응답이 성공할 경우 - {status: "fulfilled", value:result}
  • 에러가 발생한 경우 - {status: "rejected", value:error}

[3] Promise.race

    : 가장 먼저 처리된 프라미스의 결과 또는 에러를 담은 프라미스를 반환

[4] Promise.resolve

   : 주어진 값을 사용해 이행 상태의 프라미스를 만든다

[5] Promise.reject

   : 주어진 에러를 사용해 거부 상태의 프라미스를 만든다