JavaScript) Promise 와 예제

Promise

etc-image-0

JavaScript에서 비동기 작업을 효과적으로 관리하고 처리하기 위한 중요한 도구 중 하나인 Promise에 대해 알아보겠습니다. 이 글에서는 Promise의 개념, 사용법, resolvereject의 역할, 그리고 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를 사용하여 비동기 작업의 결과를 처리할 때에는 thencatch 메서드를 사용합니다.

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.allPromise.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();

 

마무리

PromiseJavaScript에서 비동기 작업을 처리하고 관리하는 강력한 도구입니다. 이 글에서는 Promise의 개념, 사용법, resolvereject의 역할, 그리고 실제 예제를 다뤄보았습니다. 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