> For the complete documentation index, see [llms.txt](https://yygeniee.gitbook.io/wil/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yygeniee.gitbook.io/wil/javascript/promise.md).

# promise

### 프라미스는 성공 또는 실패만 한다.

exeucutor는 프라미스의 상태를 이행(fulfilled) 또는 거부(rejected)로 변경시킨다.

![](https://i.imgur.com/GDJBNRw.png)

성공 혹은 실패만 한다. resolve나 reject가 되어 상태가 결정되면, 이후로는 상태를 변경할 수 없다. 처리가 끝난 프라미스에 resolve나 reject가 호출되면 무시된다.

```javascript
const testMultipleResolve = new Promise((resolve, reject) => {
  resolve("done")
  reject(new Error("error")) // 무시
  setTimeout(() => reject("error2"), 10) // 무시
})
;(async () => {
  try {
    console.log(await testMultipleResolve) // 'done'
  } catch (e) {
    console.log(e)
  }
})()
```

### resolve, reject 함수 즉시 호출하기

executor에서 꼭 비동기 연산을 수행한 후, resolve나 reject를 호출하지 않아도 된다. resolve나 reject를 즉시 호출해도 된다.

```javascript
const immediatePromise = new Promise((resolve, reject) => {
  resolve("done immediately")
})
;(() => {
  console.log(promise) // Promise { <pending> }
  console.log(immediatePromise) // Promise { 'done immediately' }
})()
```

## 소비자 : then, catch, finally

* 프라미스 객체 : executor와 소비 함수를 이어주는 역할
* 소비함수는 .then, .catch, .finally 메서드를 사용하여 등록

### then

* 두 개의 콜백 함수를 인수로 받는다.
* 첫 번째 콜백은 이행되었을 때 실행된다. resolve의 값을 받는다.
* 두 번째 콜백은 거부되었을 때 실행된다. reject의 에러를 받는다.

```javascript
promise.then(
  function (result) {
    /* 결과(result)를 다룹니다 */
  },
  function (error) {
    /* 에러(error)를 다룹니다 */
  }
)
```

* 예제

```javascript
const promise = new Promise((resolve, reject) => {
  setTimeout(() => resolve("done"), 10)
})
const rPromise = new Promise((resolve, reject) => {
  setTimeout(() => reject("error"), 10)
})

;(async () => {
  promise.then(
    (result) => console.log(`result1 : ${result}`), // result1 : done
    (error) => console.error(`reject1 ${error}`) // 실행되지 않음
  )
  rPromise.then(
    (result) => console.log(`result2 : ${result}`), // 실행되지 않음
    (error) => console.error(`reject2 ${error}`) // reject2 error
  )
})()
```

### catch

* 내부적으로 `.then(undefined, onRejectedFunction)`을 호출한다.
* catch는 프라미스를 반환한다.
  * onRejected 핸들러 안에서 `throws`가 있거나, `Promise.rejected`를 반환하면 catch가 반환하는 프라미스는 reject된다.

#### catch에서 Error 객체 반환하기

catch에서 단순히 string을 throwing하는 것 보다, **Error 인스턴스를 throwing하는게 더 좋다.** Error 인스턴스를 반환해야 stack trace와 같은 결과를 확인할 수 있다.

```javascript
Promise.reject(new Error("error instance")).catch((e) => console.error(e))
Promise.reject("just string error").catch((e) => console.error(e))
```

```
Error: error instance
    at Object.<anonymous> (/Users/kakao/study/js/promise.js:79:16)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32)
    at Function.Module._load (internal/modules/cjs/loader.js:790:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
    at internal/main/run_main_module.js:17:47
just string error
```

### finally

* 인자를 받지 않는다. 프라미스가 이행된 것인지, 거부된 것인지 확인할 수 있는 확실한 방법이 없기 때문이다.
* 프라미스가 이행 또는 거부되면, finally의 콜백이 실행된다.
* 프라미스의 결과에 상관없이 실행되어야하는 cleanup함수나 연산을 해야할 때 finally를 사용하면 좋다.
* finally가 설정한 함수가 반환하는 프라미스를 반환한다.

```javascript
function checkMail() {
  return new Promise((resolve, reject) => {
    if (Math.random() > 0.5) {
      resolve("Mail has arrived")
    } else {
      reject(new Error("Failed to arrive"))
    }
  })
}

checkMail()
  .finally(() => {
    console.log("Experiment completed")
  })
  .then((mail) => {
    console.log(mail)
  })
  .catch((err) => {
    console.error(err)
  })
```

```
Experiment completed
Mail has arrived
```

```
Experiment completed
Error: Failed to arrive
    at /Users/kakao/study/js/promise.js:95:14
    at new Promise (<anonymous>)
    at checkMail (/Users/kakao/study/js/pro
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yygeniee.gitbook.io/wil/javascript/promise.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
