JavaScript) Promise 와 예제

Promise

`JavaScript`에서 비동기 작업을 효과적으로 관리하고 처리하기 위한 중요한 도구 중 하나인 `Promise`에 대해 알아보겠습니다. 이 글에서는 `Promise`의 개념, 사용법, `resolve`와 `reject`의 역할, 그리고 `Promise`를 활용한 실제 예제에 대해 다룰 것입니다.

 

`Promise`는 비동기 작업의 성공 또는 실패를 나타내는 객체입니다. 주로 네트워크 요청, 파일 읽기, 데이터베이스 쿼리와 같은 비동기 작업을 다룰 때 사용됩니다. `Promise`는 세 가지 상태를 가질 수 있습니다.

 

  1. `Pending` (대기 중): 비동기 작업이 아직 완료되지 않은 상태입니다.
  2. `Fulfilled` (이행됨): 비동기 작업이 성공적으로 완료된 상태입니다.
  3. `Rejected` (거부됨): 비동기 작업이 실패한 상태입니다.

 

Promise 생성

`Promise`를 생성하려면 `new Promise`를 사용합니다. 아래는 기본적인 `Promise` 생성 예제입니다.

const myPromise = new Promise((resolve, reject) => {
  // 비동기 작업 수행
  if (비동기 작업 성공) {
    resolve(결과 데이터);
  } else {
    reject(에러 메시지);
  }
});

 

resolve와 reject 사용

`Promise` 내부에서 비동기 작업이 성공했을 때는 `resolve`를 호출하여 결과 데이터를 전달하고, 실패했을 때는 `reject`를 호출하여 에러 메시지를 전달합니다.

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    const success = true;
    if (success) {
      resolve("비동기 작업 성공");
    } else {
      reject("에러 발생");
    }
  }, 1000);
});

그리고 다양한 형태의 `Promise`를 만들 수 있습니다. 다음은 `try-catch`문을 활용한 `Promise`입니다.

function fetchUserData(userId) {
  return new Promise(async (resolve, reject) => {
    try {
      const user = await getUserFromDatabase(userId);
      if (!user) {
        throw new Error("사용자를 찾을 수 없습니다.");
      }

      const userData = await getUserDataFromAPI(userId);
      resolve(userData);
    } catch (error) {
      reject(error);
    }
  });
}

위의 코드에서는 `try` 블록 내에서 비동기 작업을 수행하고, 작업 중 에러가 발생하면 `catch` 블록으로 제어가 이동합니다. `catch` 블록에서는 에러를 처리하고 `reject`를 호출하여 `Promise`가 거부(rejected)됩니다. 이후 `catch` 메서드로 에러를 처리할 수 있습니다.

 

Promise 사용

`Promise`를 사용하여 비동기 작업의 결과를 처리할 때에는 `then`과 `catch` 메서드를 사용합니다.

myPromise
  .then((result) => {
    console.log("성공:", result);
  })
  .catch((error) => {
    console.error("에러:", error);
  });

`Promise`를 반환하는 함수를 호출하는 쪽에서 `try-catch` 블록을 사용하여 처리도 가능합니다.

async function main() {
  try {
    const userData = await fetchUserData(123);
    console.log("사용자 데이터:", userData);
  } catch (error) {
    console.error("에러 발생:", error.message);
  }
}

// main 함수 호출
main();

 

여러 개의 Promise 처리

여러 개의 `Promise`를 동시에 처리하거나 순차적으로 처리해야 할 때, `Promise.all`과 `Promise.race`를 활용할 수 있습니다.

  • `Promise.all`: 여러 개의 Promise가 모두 이행될 때까지 기다렸다가 결과를 반환합니다.
  • `Promise.race`: 가장 먼저 이행된 Promise의 결과 또는 거부된 Promise의 이유를 반환합니다.
// Promise.all 예제
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values);  // [3, 42, "foo"]
});

// Promise.race 예제
const promiseOne = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one');
});
const promiseTwo = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'two');
});

Promise.race([promiseOne, promiseTwo]).then((value) => {
console.log(value);  // "two" - 빨리 끝난 Promise의 결과
});

 

실제 예제

`Promise`를 사용한 실제 예제를 통해 비동기 작업을 어떻게 처리하는지 살펴보겠습니다. (예: API 요청, 파일 읽기)

function fetchData(url) {
  return new Promise((resolve, reject) => {
    fetch(url)
      .then((response) => response.json())
      .then((data) => resolve(data))
      .catch((error) => reject(error));
  });
}

fetchData("<https://api.example.com/data>")
  .then((data) => {
    console.log("데이터 가져옴:", data);
  })
  .catch((error) => {
    console.error("에러 발생:", error);
  });

여기서 꼭 알아야 하는 것은 reject를 반환하게 되면 `try-catch`문에서는 바로 `catch`로 이동하기 때문에 예상치 못한 움직임을 볼 수 있습니다. 그러니 `Promise`에 대한 이해를 하고 사용하는 것을 추천합니다.

function fetchUserData(userId) {
  return new Promise(async (resolve, reject) => {
    try {
      const user = await getUserFromDatabase(userId);
      if (!user) {
        throw new Error("사용자를 찾을 수 없습니다.");
      }

      const userData = await getUserDataFromAPI(userId);
      resolve(userData);
    } catch (error) {
      reject(error);
    }
  });
}

async function main() {
  try {
    const userData = await fetchUserData(123);
    console.log("사용자 데이터:", userData);
  } catch (error) {
    console.error("에러 발생:", error.message);
  }
}

// main 함수 호출
main();

 

마무리

`Promise`는 `JavaScript`에서 비동기 작업을 처리하고 관리하는 강력한 도구입니다. 이 글에서는 `Promise`의 개념, 사용법, `resolve`와 `reject`의 역할, 그리고 실제 예제를 다뤄보았습니다. `Promise`를 활용하여 코드를 더욱 간결하고 효율적으로 작성할 수 있습니다. 추가로 `async/await`와 함께 사용하면 더 편리한 비동기 코드를 작성할 수 있습니다.

 

'Language > JavaScript' 카테고리의 다른 글

JavaScript Symbol - 심볼  (0) 2023.10.24
JavaScript) Closure 그는 무엇인가?  (0) 2023.09.13
LocalStorage, SessionStorage  (0) 2023.01.24
Script 태그 선언 위치에 따른 오류들  (0) 2023.01.12
JavaScript(3)  (0) 2022.12.19