기타

Promise

js0616 2024. 7. 28. 03:02

Axios는 Promise 기반의 HTTP 클라이언트 라이브러리로, 브라우저와 Node.js 환경에서 모두 사용할 수 있습니다.

 

 

https://js0616.tistory.com/284

 

비동기 처리

https://www.youtube.com/watch?v=rZrbQv1bMaI  1. 비동기 처리는 왜 필요한가?Javascript는 싱글 스레드 언어 == 두 개 이상의 연산이나 함수를 동시에 실행할 수 없다는 뜻하나의 연산이 실행 중이면, 쓰레드가

js0616.tistory.com

 

배경

자바스크립트는 싱글 스레드이므로 시간이 오래걸리는 연산에 대해 비동기처리를 해야하며

비동기 함수의 처리 결과를 반환하는 경우, 순서가 보장되지 않기 때문에 그 반환 결과를 가지고 후속 처리를 하기 위해서는 비동기 함수의 콜백 함수 내에서 처리해야 한다. 비동기 처리의 순차적인 작업 및 제어 흐름을 유지하기 위해서 콜백함수를 중첩해서 사용하게 되고, 이는 콜백 헬 로 이어져 코드를 복잡하게 하고 가독성이 좋지 않으며 에러처리가 어려운 단점이 있다.

 

이에 대한 해결 방법으로 Promise  , async/await 를 사용하게 된다.

 

특징

Promise를 사용하면 비동기 작업을 연결하여 처리할 수 있고,

async/await을 사용하면 비동기 코드를 동기식으로 작성할 수 있어 가독성과 유지보수성이 높아집니다.

 

쓰는이유

콜백함수의 경우 비동기 작업 결과에 대한 처리를 콜백 함수의 중첩을 통해서 할 수 있는데, 
중첩이 심해지면 읽기 힘드니까,  Promise를 사용하여 결과 처리를 then catch 메서드를 사용해서 처리할 수 있다


 

Promise 

Promise는 비동기 처리가 성공(fulfilled)하였는지 또는 실패(rejected)하였는지 등의 상태(state) 정보를 갖는다.

 

Promise 객체는 요청의 성공(resolve) 또는 실패(reject) 에 따라 상태가 변경되고,

각 상태(성공, 실패)에 따라서 then(), catch(), finally() 메서드를 사용하여 콜백함수로 처리할 수 있습니다.

// Promise 객체 생성
const myPromise = new Promise((resolve, reject) => {
  // 비동기 작업 수행
  setTimeout(() => {
    const randomNumber = Math.random();
   
    // 랜덤 숫자가 0.5보다 크면 성공(resolve)
    if (randomNumber > 0.5) {
      resolve(randomNumber);
    } else { // 그렇지 않으면 실패(reject)
      reject(new Error('랜덤 숫자가 0.5보다 작습니다.'));
    }
  }, 1000); // 1초 후에 실행
});

console.log('작업 시작')
// Promise를 사용하여 비동기 작업 처리
myPromise
  .then(result => {
    console.log('성공:', result);
  })
  .catch(error => {
    console.error('실패:', error.message);
  })
  .finally(()=>{
    console.log('작업 종료')
  });

  console.log('작업 진행 중...')

 

'작업 시작', '작업 진행 중...'은 동기적으로 실행되고, 비동기 작업은 백그라운드에서 실행되어 비동기적으로 처리됩니다.

  1. const myPromise = new Promise((resolve, reject) => { ... });: Promise 객체가 생성됩니다. 이 때 전달된 함수 내에서는 비동기 작업이 수행됩니다. 여기서는 setTimeout을 사용하여 1초 후에 랜덤 숫자를 생성하고, 이에 따라 resolve 또는 reject 함수를 호출합니다.
  2. console.log('작업 시작'): 동기적으로 실행되는 코드입니다. 이 코드는 Promise 객체 생성 후 즉시 실행되어 '작업 시작'이라는 메시지를 출력합니다.
  3. myPromise.then(result => { ... }): then() 메서드를 사용하여 Promise 객체의 비동기 작업이 완료된 후의 처리를 정의합니다. 이 코드는 myPromise 객체가 생성되고, 비동기 작업이 완료된 이후에 실행됩니다. 이때까지는 then() 메서드 내의 콜백 함수가 실행되지 않습니다.
  4. console.log('작업 진행 중...'): then() 메서드 이후에 바로 실행되는 코드입니다. 이 코드는 then() 메서드 호출 후 즉시 실행되어 '작업 진행 중...'이라는 메시지를 출력합니다.
  5. 비동기 작업인 setTimeout이 실행되고, 1초 후에 resolve 또는 reject 함수가 호출됩니다. 이 때, 랜덤 숫자에 따라 resolve가 호출되어 then() 메서드의 콜백 함수가 실행될 수도 있고, reject가 호출되어 catch() 메서드의 콜백 함수가 실행될 수도 있습니다.
  6. 만약 비동기 작업이 성공적으로 완료되어 resolve가 호출된 경우, then() 메서드의 콜백 함수가 실행되어 '성공: [결과값]'이라는 메시지가 출력됩니다.
  7. 만약 비동기 작업에서 오류가 발생하여 reject가 호출된 경우, catch() 메서드의 콜백 함수가 실행되어 '실패: [에러 메시지]'가 출력됩니다.
  8. 성공 또는 실패 여부와 관계없이 마지막에 항상 실행할 콜백 함수를 등록합니다.

 


Promise.all

Promise.all 메소드는 프로미스가 담겨 있는 배열 등의 이터러블을 인자로 전달 받는다.

그리고 전달받은 모든 프로미스를 병렬로 처리하고 그 처리 결과를 resolve하는 새로운 프로미스를 반환한다.

 

Promise.all([
  new Promise(resolve => setTimeout(() => resolve(1), 3000)), // 1
  new Promise(resolve => setTimeout(() => resolve(2), 2000)), // 2
  new Promise(resolve => setTimeout(() => resolve(3), 1000))  // 3
]).then(console.log) // [ 1, 2, 3 ]
  .catch(console.log);

 

 

Promise.all 메소드는 3개의 프로미스를 담은 배열을 전달받았다. 각각의 프로미스는 아래와 같이 동작한다.

  • 첫번째 프로미스는 3초 후에 1을 resolve하여 처리 결과를 반환한다.
  • 두번째 프로미스는 2초 후에 2을 resolve하여 처리 결과를 반환한다.
  • 세번째 프로미스는 1초 후에 3을 resolve하여 처리 결과를 반환한다.

Promise.all 메소드는 전달받은 모든 프로미스를 병렬로 처리한다. 이때 모든 프로미스의 처리가 종료될 때까지 기다린 후 아래와 모든 처리 결과를 resolve 또는 reject한다.

  • 모든 프로미스의 처리가 성공하면 각각의 프로미스가 resolve한 처리 결과를 배열에 담아 resolve하는 새로운 프로미스를 반환한다. 이때 첫번째 프로미스가 가장 나중에 처리되어도 Promise.all 메소드가 반환하는 프로미스는 첫번째 프로미스가 resolve한 처리 결과부터 차례대로 배열에 담아 그 배열을 resolve하는 새로운 프로미스를 반환한다. 즉, 처리 순서가 보장된다.
  • 프로미스의 처리가 하나라도 실패하면 가장 먼저 실패한 프로미스가 reject한 에러를 reject하는 새로운 프로미스를 즉시 반환한다.

 

Promise.race

Promise.all 메소드와 동일하게 프로미스가 담겨 있는 배열 등의 이터러블을 인자로 전달 받는다. 

이때, 가장 먼저 처리된 프로미스가 resolve한 처리 결과를 resolve하는 새로운 프로미스를 반환한다.

하나라도 실패하면 가장 먼저 실패한 프로미스가 reject한 에러를 reject하는 새로운 프로미스를 즉시 반환한다.

 

 




Promise 예시

function fetchData() {
    return new Promise((resolve, reject) => {
      // 비동기 작업 수행
      setTimeout(() => {
        const data = '데이터';
        resolve(data);
      }, 1000);
    });
  }
 
  fetchData()
    .then(data => {
      console.log('첫 번째 데이터 처리 완료:', data);
      return fetchData(); // 다음 비동기 작업
    })
    .then(data => {
      console.log('두 번째 데이터 처리 완료:', data);
      return fetchData(); // 다음 비동기 작업
    })
    .then(data => {
      console.log('세 번째 데이터 처리 완료:', data);
    })
    .catch(error => {
      console.error('에러 발생:', error);
    });
 

 

 

async/await 예시

async function fetchData() {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        const data = '데이터';
        resolve(data);
      }, 1000);
    });
  }
 
  async function processData() {
    try {
      const data1 = await fetchData();
      console.log('첫 번째 데이터 처리 완료:', data1);
 
      const data2 = await fetchData();
      console.log('두 번째 데이터 처리 완료:', data2);
 
      const data3 = await fetchData();
      console.log('세 번째 데이터 처리 완료:', data3);
    } catch (error) {
      console.error('에러 발생:', error);
    }
  }
 
  processData();

 

 

Axios는 자바스크립트와 Node.js를 위한 HTTP 클라이언트 라이브러리로, Promise 기반으로 HTTP 요청을 처리합니다.

const axios = require('axios');

// GET 요청 보내기
  .then(response => {
    console.log('응답 데이터:', response.data);
  })
  .catch(error => {
    console.error('오류 발생:', error);
  });

 

 

 

 

 

 

 

 

 

 

 

https://poiemaweb.com/es6-promise

 

Promise | PoiemaWeb

Promise는 비동기 처리가 성공(fulfilled)하였는지 또는 실패(rejected)하였는지 등의 상태(state) 정보를 갖는다. Promise는 Promise 생성자를 통해 인스턴스화한다. Promise 생성자는 비동기 작업을 수행할 콜

poiemaweb.com