개발공부/Javascript

#기본기9_Promise

킴승 2024. 4. 3. 01:55

Promise(프로미스)는 자바스크립트에서 비동기 작업을 처리하는 객체입니다.

주로 네트워크 요청이나 파일 읽기 등 시간이 걸리는 작업을 처리할 때 사용됩니다.

Promise는 비동기 작업이 완료되었을 때 성공 또는 실패 여부에 따라 처리할 수 있는 콜백 함수를 제공합니다.

 

** 비동기(asynchronous)란 한 작업이 완료되기 전에 다른 작업을 동시에 수행할 수 있는 것을 의미합니다.

이는 작업이 순차적으로 실행되는 동기(synchronous) 방식과는 달리, 작업의 완료 여부와 상관없이 다음 작업을 진행할 수 있음을 의미합니다.

 

Promise는 세 가지 상태를 가질 수 있습니다:

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

 

new Promise에 전달되는 함수를 executor(실행자, 실행함수)라고 부른다.

new Promise가 만들어질 때 자동으로 수행되는데 처음 상태(state)는 pending, 결과(result)는 undefined이다.

 

이후 처리 성공여부에 따라 state와 result가 바뀌게 된다.

성공시 state는 fulfilled, result는 특정value

실패시 state는 rejected, result는 error 로 변경된다.

// 성공
let promise = new Promise(function(resolve, reject) { // 여기서 function이 executor함수
	 // 1초 뒤에 일이 성공적으로 끝났다는 신호가 전달되면서 result는 '완료'가 됩니다.
 	setTimeout(() => resolve("완료"), 1000);
})

// 실패
let promise = new Promise(function(resolve, reject){
	setTimeout(()=> reject(new Error("에러 발생")),1000);
});

 

executor는 인자로 resolve와 reject함수를 받는다. (자바스크립트가 미리 정의한 함수이므로 따로 세팅하는게 아님)

resolve나 reject중 하나는 반드시 호출해야한다.

 

송신자 : Promise객체를 생성해서 resolve 혹은 reject처리를 해서 전달

수신자 : .then() / .catch() / .finally() 를 통해서 상태와 결과를 수신한다.

 

  1. .then() : Promise 가 성공(이행)했을 때, 실패(거부)했을 때의 처리를 정의한다.
  2. catch() : Promise가 실패했을 때의 처리를 정의한다.
  3. finally() : Promise가 성공 or 실패했을 때 공통적으로 처리할 작업을 정의한다.
// 성공
let promise = new Promise(function(resolve, reject) { // 여기서 function이 executor함수
	 // 1초 뒤에 일이 성공적으로 끝났다는 신호가 전달되면서 result는 '완료'가 됩니다.
 	setTimeout(() => resolve("완료"), 1000);
})

 // promise.then(onFulfiiled, onRejected) 
 // 첫번째는 Promise가 성공했을 때 실행할 콜백함수
 // 두번째는 Promise가 실패했을 때 실행할 콜백함수 이다.
 
 promise.then( 
   // result ,error는 다른 단어로 작성해도 상관없음, 첫번째 함수가 성공용콜백, 두번째 함수가 실패용 콜백인 순서만 지키면 된다. 
 	result => alert(result)  // 1초 후 완료를 출력한다 
    error => alert(error) // Promise에서 실패를 전달하지 않으므로 실행되지 않음
 )

 

// catch
let promise = new Promise((resolve, reject) => {
  setTimeout(() => reject(new Error("에러발생")) , 1000);
});

// 수신자
// promise.catch(onRejected); 인자로 실패(거부)함수 하나를 받는다.

promise.catch(error) // 1초 후 에러발생 alert창 실행됨
// finally
fetch('https://api.example.com/data')
  .then(response => {
    // 성공적으로 응답 받았을 때 수행할 작업
    console.log('Data retrieved successfully:', response);
    return response.json();
  })
  .then(data => {
    // 데이터 처리
    console.log('Processed data:', data);
  })
  .catch(error => {
    // 오류 처리
    console.error('An error occurred:', error);
  })
  .finally(() => {
    // 항상 실행되는 작업
    console.log('Cleanup or finalization code here');
  });

 

.finally()는 사용해본적이 없다. 어떤 상황에서 사용하지?

 

GPT씨

.finally() 메서드는 주로 다음과 같은 상황에서 활용됩니다:

  1. 리소스 정리: 비동기 작업이 완료된 후에는 사용한 리소스를 정리해야 할 수 있습니다. 예를 들어, 파일을 열고 읽는 작업을 수행한 후 파일을 닫는 작업을 .finally() 메서드 내에서 수행할 수 있습니다.
  2. 로딩 표시 숨기기: 웹 애플리케이션에서 데이터를 비동기적으로 로드할 때, 로딩 표시를 표시한 후 데이터가 로드되면 해당 표시를 숨기는 것이 일반적입니다. .finally() 메서드를 사용하여 데이터 로드가 완료되면 로딩 표시를 숨기는 작업을 수행할 수 있습니다.
  3. 로그 기록: 비동기 작업이 완료된 후에는 해당 작업에 대한 로그를 기록하는 것이 유용할 수 있습니다. 예를 들어, 서버에 데이터를 보내는 HTTP 요청을 보낸 후에는 요청이 성공했는지 또는 실패했는지에 대한 로그를 기록할 수 있습니다.
  4. UI 업데이트: 웹 애플리케이션에서 비동기 작업이 완료된 후에는 UI를 업데이트해야 할 수 있습니다. 예를 들어, 새로운 데이터를 가져온 후 UI를 업데이트하여 사용자에게 최신 정보를 표시할 수 있습니다.
  5. 캐시 업데이트: 비동기 작업이 완료된 후에는 캐시를 업데이트해야 할 수 있습니다. 이는 데이터를 다시 요청하지 않고 캐시된 데이터를 사용하여 성능을 향상시킬 수 있습니다.

이러한 상황에서 .finally() 메서드를 사용하여 비동기 작업이 완료된 후에 실행되어야 하는 작업을 처리할 수 있습니다. 이는 코드의 가독성과 유지보수성을 향상시키며, 비동기 작업의 완료 후 추가적인 작업을 효율적으로 처리할 수 있도록 도와줍니다.

 

Promise를 직접 작성해본적은 없다. (Promise all은 있네..)

일반적으로 async/await 구문을 통해 비동기 작업을 처리한다.

 

직접 Promise 객체를 만드는 상황

  1. 자체적인 비동기 작업을 처리하는 함수를 만들거나
  2. 다른 비동기 작업을 추상화하고 캡슐화할 필요가 있는 경우
  3. 프로미스의 동작 방식을 이해하고 싶은 경우

다음엔 async / await 를 알아보자.