JavaScript Promises로 비동기 작업 처리하기: 초보자 가이드
JavaScript Promises로 비동기 작업 처리하기: 초보자 가이드
JavaScript에서 비동기 작업을 처리하는 것은 필수적인 능력입니다. 어떨 때는 서버에서 데이터를 가져오고, 때로는 긴 연산을 비동기적으로 처리해야 합니다. 비동기 작업을 효과적으로 다루기 위해 등장한 개념이 바로 Promises
입니다. 이 가이드에서는 Promises가 무엇인지, 왜 중요한지, 그리고 이를 어떻게 사용할 수 있는지에 대해 자세히 설명하려고 합니다.
Promises란 무엇인가?
Promises
는 JavaScript에서 비동기 작업을 처리하기 위한 객체입니다. Promise
객체는 아직 완료되지 않은 작업의 최종 결과값을 나타냅니다. Promises는 주로 다음 세 가지 상태를 가집니다:
- Pending (대기): 초기 상태, 아직 비동기 작업이 완료되지 않았습니다.
- Fulfilled (이행): 비동기 작업이 성공적으로 완료되었습니다.
- Rejected (거부): 비동기 작업이 실패했습니다.
Promises는 한 번 처리되면(이행되거나 거부되면) 그 상태를 유지하며, 이후에는 변경되지 않습니다. 비동기 작업이 완료되면 then
메서드를 사용하여 이행된 결과값에 접근하거나, catch
메서드를 사용하여 거부된 이유를 처리할 수 있습니다.
예제: 간단한 Promise 생성하기
다음은 간단한 Promise
객체를 생성하는 예제입니다. 이 경우, Promise는 2초 후에 이행됩니다.
javascriptconst myPromise = new Promise((resolve, reject) => { setTimeout(() => { resolve('Promise 이행 완료!'); }, 2000); }); myPromise.then(result => { console.log(result); // 'Promise 이행 완료!' 출력 }).catch(error => { console.error(error); });
이 예제에서 setTimeout
함수는 2초 후에 resolve
함수를 호출합니다. then
메서드는 Promise가 이행되었을 때 호출되며, 결과값을 인수로 받습니다.
왜 Promises가 중요한가?
Promises
는 JavaScript에서 비동기 코드를 처리하는 방법을 개선하는 몇 가지 중요한 이유가 있습니다:
- 가독성 향상: Promises는 콜백 헬(callback hell)을 جلوگیری하여 코드의 가독성을 높입니다. 콜백 헬은 중첩된 콜백 함수들로 인해 코드가 복잡해지는 현상을 말합니다.
- 에러 처리의 일관성: Promises는 에러 처리를 구조화된 방식으로 처리할 수 있습니다.
catch
메서드를 사용하면 항상 동일한 방식으로 에러를 처리할 수 있습니다. - 체이닝: Promises는
then
과catch
메서드를 활용한 체이닝이 가능합니다. 여러 비동기 작업을 순차적으로 처리할 때 유용합니다.
예제: 콜백 헬과 Promise 비교
콜백 헬의 예제를 먼저 살펴봅시다.
javascriptasyncFunction1(function(result1) { asyncFunction2(result1, function(result2) { asyncFunction3(result2, function(result3) { console.log('최종 결과:', result3); }); }); });
이제 같은 작업을 Promises를 사용하여 구현해 보겠습니다.
javascriptasyncFunction1() .then(result1 => asyncFunction2(result1)) .then(result2 => asyncFunction3(result2)) .then(result3 => { console.log('최종 결과:', result3); }) .catch(error => { console.error('에러 발생:', error); });
Promise API
Promises는 내장된 여러 메서드를 통해 강력하고 유연한 비동기 처리가 가능합니다. 그 중 몇 가지 주요 메서드를 살펴보겠습니다.
Promise.all
Promise.all
메서드는 주어진 모든 Promise
가 이행될 때까지 기다렸다가, 각각의 결과값을 배열로 반환합니다. 만약 하나라도 거부되면, 즉시 거부된 이유를 반환합니다.
javascriptconst promise1 = Promise.resolve(3); const promise2 = new Promise((resolve, reject) => setTimeout(resolve, 2000, 'foo')); const promise3 = 42; Promise.all([promise1, promise2, promise3]).then(values => { console.log(values); // [3, 'foo', 42] 출력 }).catch(error => { console.error(error); });
Promise.race
Promise.race
메서드는 가장 먼저 이행되거나 거부된 Promise
의 결과값 또는 거부 이유를 반환합니다.
javascriptconst promise1 = new Promise((resolve, reject) => setTimeout(resolve, 500, '1번 이행')); const promise2 = new Promise((resolve, reject) => setTimeout(resolve, 100, '2번 이행')); Promise.race([promise1, promise2]).then(value => { console.log(value); // '2번 이행' 출력 }).catch(error => { console.error(error); });
Promise.allSettled
Promise.allSettled
메서드는 주어진 모든 Promise
가 이행되거나 거부될 때까지 기다립니다. 모든 결과를 객체 배열로 반환하며, 각각은 status
필드와 value
또는 reason
필드를 가집니다.
javascriptconst promise1 = Promise.resolve('이행됨'); const promise2 = Promise.reject('거부됨'); Promise.allSettled([promise1, promise2]).then(results => { results.forEach((result) => console.log(result.status)); }); // 출력: 'fulfilled', 'rejected'
결론
JavaScript의 Promises
는 비동기 작업을 좀 더 직관적이고 관리하기 쉽게 해주는 강력한 도구입니다. Promises
를 이해하고 효과적으로 사용하는 것은 현대 JavaScript 개발자의 필수 능력 중 하나입니다. 이 가이드를 통해 Promises
의 기본 개념과 사용법을 이해하는 데 도움이 되었기를 바랍니다.