하얀 코딩

[JavaScript - 21] Promise 본문

JavaScript

[JavaScript - 21] Promise

whitecoding 2023. 1. 11. 23:45

Promise

비동기로 작동하는 코드를 제어할 수 있는 다른 방법 중 Promise를 활용하는 방법이 있습니다.

 

Promise는 class이기 때문에 new 키워드를 통해 Promise 객체를 생성합니다. 또한 Promise는 비동기 처리를 

수행할 콜백 함수(executor)를 인수로 전달받는데 이 콜백 함수는 resolve, reject 함수를 인수로 전달받습니다.

let promise = new Promise((resolve, reject) => {
  // executor(실행자): 여기에는 개발자가 수행할 작업을 알아서 코딩합니다.
  
  resolve(1); // 일이 성공적으로 끝난 경우 그 결과를 나타내는 1 값과 함께 호출을 표현했다.
  
  reject(error); //  실패 했을 경우 에러 객체를 나타내는 error와 함께 호출을 표현했다.
});

executor의 인수 resolve와 reject는 자바스크립트에서 자체 제공하는 콜백입니다. 

개발자는 resolve와 reject를 신경 쓰지 않고 executor 안 코드만 작성하면 됩니다.

 

대신 executor에선 결과를 즉시 얻든 늦게 얻든 상관없이 상황에 따라 인수로 넘겨준 콜백 중 하나를 반드시 호출해야 합니다.

 

요약하면 다음과 같습니다.

executor는 자동으로 실행되는데 여기서 원하는 일이 처리됩니다. 

처리가 끝나면 executor는 처리 성공 여부에 따라 resolve나 reject를 호출합니다.


Promise 객체의 내부 프로퍼티

state

처음엔 "pending"(보류)이었다 resolve가 호출되면 "fulfilled", reject가 호출되면 "rejected"로 변합니다.

 

result

처음엔 undefined이었다 resolve(value)가 호출되면 value로, reject(error)가 호출되면 error로 변합니다.

[ 그림 ] Promise의 반환과 상태 변화 이해하기


✅ promise는 성공 또는 실패만 합니다.


executor는 resolve나 reject 중 하나를 반드시 호출해야 합니다. 이때 변경된 상태는 더 이상 변하지 않습니다
처리가 끝난 프라미스에 resolve와 reject를 호출하면 무시되죠.

let promise = new Promise(function(resolve, reject) {
  resolve("완료");

  reject(new Error("…")); // 무시됨
  setTimeout(() => resolve("…")); // 무시됨
});

이렇게 executor에 의해 처리가 끝난 일은 결과 혹은 에러만 가질 수 있습니다.

여기에 더하여 resolve나 reject는 인수를 하나만 받고(혹은 아무것도 받지 않음) 그 이외의 인수는 무시한다는 특성도 있습니다.

 


❗Error 객체와 함께 거부하기


무언가 잘못된 경우, executor는 reject를 호출해야 합니다. 이때 인수는 resolve와 마찬가지로 어떤 타입도 가능하지만,

Error 객체 또는 Error를 상속받은 객체를 사용할 것을 추천합니다. 


❗resolve·reject 함수 즉시 호출하기

 

executor는 대개 무언가를 비동기적으로 수행하고, 약간의 시간이 지난 후에 resolve, reject를 호출하는데, 

꼭 이렇게 할 필요는 없습니다. 아래와 같이 resolve나 reject를 즉시 호출할 수도 있습니다.

let promise = new Promise(function(resolve, reject) {
  // 일을 끝마치는 데 시간이 들지 않음
  resolve(123); // 결과(123)를 즉시 resolve에 전달함
});

어떤 일을 시작했는데 알고 보니 일이 이미 끝나 저장까지 되어있는 경우, 

이렇게 resolve나 reject를 즉시 호출하는 방식을 사용할 수 있습니다.

이렇게 하면 promise는 즉시 이행 상태가 됩니다.


state와 result는 내부에 있습니다.

 

프라미스 객체의 state, result 프로퍼티는 내부 프로퍼티이므로 개발자가 직접 접근할 수 없습니다. 

.then() .catch() .finally() 메서드를 사용하면 접근 가능한데, 이 내용은 바로 다음 페이지에서 확인하겠습니다!