자바스크립트에서의 Promise 클래스

자바스크립트에서의 Promise 클래스

이 글에서는 자바스크립트의 Promise 클래스를 설명합니다.

YouTube Video

Promise

Promise 클래스는 비동기 작업을 처리하기 위한 클래스입니다. 작업이 성공하면 결과를 처리하고, 실패하면 에러 처리를 수행합니다. 전통적으로 비동기 작업이 완료되기를 기다릴 때 콜백 함수를 사용했으나, Promise는 이를 보다 명확하고 강력하게 만듭니다.

1const promise = new Promise((resolve, reject) => {
2    setTimeout(() => resolve("Done!"), 1000);
3});
4
5// Displays "Done!" after 1 second
6promise.then(result => console.log(result));
  • 이 코드는 1초 후에 "Done!"을 표시하는 비동기 프로세스의 예시입니다.
    • 먼저, new Promise를 사용하여 새로운 Promise 객체를 생성합니다. 인수는 두 개의 콜백을 받는 함수입니다. 성공 시 resolve, 실패 시 reject가 호출됩니다.
    • setTimeout을 사용하여 1초 후에 resolve()를 호출합니다.
    • promise 객체의 then() 메서드는 완료를 기다리고 결과를 표시합니다.

기본 구조

Promise는 결국 성공 또는 실패 중 하나의 결과를 반환하는 객체입니다.

 1const promise = new Promise((resolve, reject) => {
 2    // Asynchronous operation
 3    // Flag indicating whether the operation was successful
 4    const success = true;
 5
 6    if (success) {
 7        resolve('Operation successful!');
 8    } else {
 9        reject('An error occurred');
10    }
11});
  • 성공의 경우, resolve()가 호출됩니다.
  • 실패의 경우, reject()가 호출됩니다.

Promise 객체는 세 가지 상태를 가집니다.

1promise
2    .then((result) => {
3        console.log(result);
4    })
5    .catch((error) => {
6        console.error(error);
7    })
  • 대기 중
    • 비동기 프로세스가 아직 완료되지 않았습니다.
  • 이행됨
    • 비동기 프로세스가 성공하여 resolve()를 통해 결과가 반환되었습니다. 결과는 then() 메서드를 사용해 받을 수 있습니다.
  • 거부됨
    • 비동기 프로세스가 실패하여 reject()를 통해 오류가 발생했습니다. 오류는 catch() 메서드를 사용해 받을 수 있습니다.

then()catch() 메서드

Promise를 사용하여 비동기 작업이 완료되었을 때 수행할 작업을 정의할 수 있습니다. 이를 위해 then()catch() 메서드를 사용합니다.

then()

1const promise = new Promise((resolve, reject) => {
2    resolve('Operation successful!');
3});
4
5promise.then((result) => {
6    console.log(result);  // "Operation successful!"
7});
  • then() 메서드는 Promise가 성공했을 때 호출할 함수를 지정합니다.

catch()

1const promise = new Promise((resolve, reject) => {
2    reject('An error occurred');
3});
4
5promise.catch((error) => {
6    console.error(error);  // "An error occurred"
7});
  • catch() 메서드는 Promise가 실패했을 때 호출할 함수를 지정합니다.

finally() 메서드

 1const promise = new Promise((resolve, reject) => {
 2    resolve('Operation successful!');
 3});
 4
 5promise
 6    .then((result) => {
 7        console.log(result);
 8    })
 9    .catch((error) => {
10        console.error(error);
11    })
12    .finally(() => {
13        console.log('The operation has completed');
14    });
  • finally() 메서드는 Promise가 성공했든 실패했든 상관없이 최종적으로 실행할 코드를 정의합니다.

then() 체인

then()은 새로운 Promise를 반환하므로, 다음 then()체이닝할 수 있습니다.

 1const promise = new Promise((resolve, reject) => {
 2    setTimeout(() => {
 3        resolve(1);
 4    }, 1000);
 5});
 6
 7promise
 8    .then(result => {
 9        console.log(result); // 1
10        return result + 1;
11    })
12    .then(result => {
13        console.log(result); // 2
14        return result + 1;
15    })
16    .then(result => {
17        console.log(result); // 3
18    })
19    .catch(error => {
20        console.error(error.message); // Something went wrong
21    });
  • 이 코드에서 초기 resolve()는 값 1을 넘기고, 각 then이 반환하는 값은 다음 then으로 전달됩니다.
  • catch()를 사용하면 체인 내에서 발생하는 어떠한 에러도 한 곳에서 처리할 수 있습니다.

실용적인 예

예를 들어, Promise는 서버에서 데이터를 가져오기 위해 자주 사용됩니다. fetch() API를 사용하는 예를 살펴봅시다.

 1fetch('https://codesparklab.com/json/example.json')
 2    .then(response => {
 3        if (!response.ok) {
 4            throw new Error('Network error');
 5        }
 6        return response.json();
 7    })
 8    .then(data => {
 9        console.log(data);
10    })
11    .catch(error => {
12        console.error('Error:', error);
13    });
  • 이 코드에서 fetch()Promise를 반환하기 때문에, 서버로부터 응답을 받은 후 데이터를 처리하기 위해 then()이 사용됩니다. catch()를 사용하여 오류를 처리합니다.

여러 Promise 처리하기

Promise.all()

여러 Promise를 동시에 실행하고 모두 성공했을 때만 진행하려면 Promise.all()을 사용하세요.

 1const promise1 = Promise.resolve(1);
 2const promise2 = Promise.resolve(2);
 3const promise3 = Promise.resolve(3);
 4
 5Promise.all([promise1, promise2, promise3])
 6    .then((results) => {
 7        console.log(results);  // [1, 2, 3]
 8    })
 9    .catch((error) => {
10        console.error('Error :', error);
11    });
  • 모든 Promise가 성공했을 때만 then()이 호출됩니다. 하나라도 실패하면 catch()가 호출됩니다.

Promise.allSettled()

여러 Promise를 동시에 실행하고, 성공이나 실패에 관계없이 모든 결과를 얻고 싶다면 Promise.allSettled()를 사용하세요.

 1const promise1 = Promise.resolve(1);
 2const promise2 = Promise.reject("Failed");
 3const promise3 = Promise.resolve(3);
 4
 5Promise.allSettled([promise1, promise2, promise3])
 6    .then((results) => {
 7        results.forEach(result => console.log(result));
 8        // [
 9        //   { status: 'fulfilled', value: 1 },
10        //   { status: 'rejected', reason: 'Failed' },
11        //   { status: 'fulfilled', value: 3 }
12        // ]
13    });
  • 모든 Promise가 해결(이행 또는 거부)되면 then()이 호출됩니다. 각 결과에는 status 속성('fulfilled' 또는 'rejected')이 포함되어 있습니다. 일부가 실패하더라도 다른 작업에는 영향을 주지 않습니다.

Promise.race()

Promise.race()는 먼저 이행되거나 거부된 Promise의 결과를 반환합니다.

1const promise1 = new Promise((resolve) => setTimeout(resolve, 100, 'First'));
2const promise2 = new Promise((resolve) => setTimeout(resolve, 500, 'Second'));
3
4Promise.race([promise1, promise2]).then((result) => {
5    console.log(result);  // "First"
6});
  • 이 예제처럼, 가장 먼저 완료된 Promise의 결과가 반환됩니다.

async/await와의 관계

async/await 문법을 사용하면 Promise를 더 직관적으로 작성할 수 있습니다. async 함수는 항상 Promise를 반환하며, awaitPromise가 해결될 때까지 기다립니다.

 1async function fetchData() {
 2    try {
 3        const response = await fetch('https://codesparklab.com/json/example.json');
 4        const data = await response.json();
 5        console.log(data);
 6    } catch (error) {
 7        console.error('Error :', error);
 8    }
 9}
10
11fetchData();

이와 같이 async/await를 사용하면 비동기 작업을 동기 코드처럼 작성할 수 있어 가독성이 높아집니다.

요약

  • Promise는 비동기 작업의 성공 또는 실패를 처리하기 위한 객체입니다.
  • then()으로 성공 작업을 처리하고, catch()로 오류를 처리합니다.
  • finally()는 성공 여부와 관계없이 마지막에 실행되는 코드를 정의합니다.
  • Promise.all() 또는 Promise.race()를 사용하여 여러 Promise를 함께 처리할 수 있습니다.
  • async/awaitPromise를 더 간단하게 작성하기 위한 문법입니다.

위의 기사를 보면서 Visual Studio Code를 사용해 우리 유튜브 채널에서 함께 따라할 수 있습니다. 유튜브 채널도 확인해 주세요.

YouTube Video