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

# Refresh Promise

## 1. 프로미스 코드 - 기초&#x20;

아래 코드는 간단한 ajax 통신 코드이다.&#x20;

```javascript
function getData(callbackFunc) {
  $.get('url 주소/products/1', function(response) {
    callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
  });
}

getData(function(tableData) {
  console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});
```

위 코드에 프로미스를 적용하면  아래와 같은 코드가 된다.&#x20;

```javascript
function getData(callback) {
  // new Promise() 추가
  return new Promise(function(resolve, reject) {
    $.get('url 주소/products/1', function(response) {
      // 데이터를 받으면 resolve() 호출
      resolve(response);
    });
  });
}

// getData()의 실행이 끝나면 호출되는 then()
getData().then(function(tableData) {
  // resolve()의 결과 값이 여기로 전달됨
  console.log(tableData); // $.get()의 reponse 값이 tableData에 전달됨
});
```

## 2. 여러개의 프로미스 연결&#x20;

### 2.1 예제 1

&#x20;콜백 함수를 사용해서 시간 지연에 따라 Data()객체를 출력하는 코드이다.&#x20;

```javascript
function delay(sec, callback) {
    return window.setTimeout(() => {
        callback(new Date().toISOString()) 
        // new Date().toISOString()를 callback함수의 인자인 result에 전달 
    }, sec * 1000)
}

delay(1, (result) => {
    console.log(1, result)
    
    delay(1, (result) => {
        console.log(2, result)
        
        delay(1, (result) => {
            console.log(3, result)
        })
    })
})
```

```javascript
// 출력 되는 값
1 "2021-04-01T02:58:52.364Z"
2 "2021-04-01T02:58:53.366Z"
3 "2021-04-01T02:58:54.369Z"
```

위 코드에 프로미스를 적용하면  아래와 같은 코드가 된다.&#x20;

```javascript
function delay(sec) {
    return new Promise((resolve, reject) => {
        window.setTimeout(() => {
            resolve(new Date().toISOString()) 
        }, sec * 1000)
    }) 
}

delay(1).then((result) => {
    console.log(1, result)
    return delay(1)
}).then((result) => {
    console.log(2, result)
    return delay(1)
}).then((result) => {
    console.log(3, result)})
```

`delay()` 함수가 실행되면 Promise 객체가 대기 상태에서 바로 이행 상태가 되기 때문에 `then()`으로 넘어가면서 `resolve()`의 인자를 `result`에 넘겨주게 된다. \
그리고 첫 번째, `then()`에서는 `delay(1)`를 반환하여 Promise 객체를 반환한다. 1초 후 두 번째, `then()`이 실행되고 다시 Promise 객체를 반환하는 `delay(1)` 함수를 반환해서 1초 후 세 번째 `then()`으로 넘어가게 된다.&#x20;

{% hint style="info" %}
&#x20;Promise를 사용한 코드에서 1, 2, 3초 뒤에 log가 출력되게 하려면 아래와 같은 코드를 사용해야 한다. 하지만 이것은 콜백함수와 다를게 없다. 그렇기 때문에 첫번째 코드가 끝나면 다시 Promise 객체가 반환되어 `then()` 메서드를 사용할 수 있도록 코드를 만든다.&#x20;

```javascript
delay(1).then((result) => {
    console.log(1, result)
    
    delay(1).then((result) => {
        console.log(2, result)
    
        delay(1).then((result) => {
            console.log(3, result)
        })
    })
})
```

만약 delay 함수를 리턴하지 않으면 어떻게 출력 될까?&#x20;

```javascript
delay(1).then((result) => {
    console.log(1, result)
    
}).then((result) => {
    console.log(2, result)
    
}).then((result) => {
    console.log(3, result)})
```

반환되는 값 없이 체이닝 메서드를 사용하면 처음에 나온 결과값을 가공하는 형식으로 작업이 진행되기 때문에 `undefined`가 된다. &#x20;

```javascript
// 출력되는 값
1 "2021-04-01T03:02:51.260Z"
2 undefined
3 undefined
```

{% endhint %}

### 2.2 예제 2&#x20;

위와 같은 setTimeout()을 사용한 예제이다. 하지만 위의 예제와 다른 점은 then()의 return 값이 Promise를 반환하는 함수가 아니라는 것이다.&#x20;

```javascript
new Promise(function(resolve, reject){
  setTimeout(function() {
    resolve(1);
  }, 2000);
})
.then(function(result) {
  console.log(result); // 1
  return result + 10;
})
.then(function(result) {
  console.log(result); // 11
  return result + 20;
})
.then(function(result) {
  console.log(result); // 31
});
```

```javascript
// 출력 되는 값
1
11
31 
```

&#x20;위의 코드는 2초 후 1, 11, 31 숫자를 출력하는 Promise 코드이다.&#x20;

`resolve()`가 호출되면 프로미스가 대기 상태에서 이행 상태로 넘어가기 때문에 첫 번째 `.then()`의 로직으로 넘어간다. 첫 번째 `.then()`에서는 이행된 결과 값 1을 받아서 10을 더한 후 그다음 `.then()` 으로 넘겨준다. 두 번째 `.then()`에서도 마찬가지로 바로 이전 프로미스의 결과 값 11을 받아서 20을 더하고 다음 `.then()`으로 넘겨준다. 마지막 `.then()`에서 최종 결과 값 31을 출력한다.&#x20;

### 2.2 분석 &#x20;

두 가지 예제를 살펴보면 Promise를 적용 후 callback 함수를 받는 인자의 역할을 resolve가 대신 한다는 것을 알 수 있다. 이 처럼 resolve는 Promise가 성공 시 실행되는 함수이다.&#x20;

### 2.4 프로미스 반환 vs 결과 값 반환&#x20;

예제 1은 then()에서 가공된 결과 값을 다음 then()에 넘겨주는 방식이다. 반면에 예제 2는 Promise객체를 반환하는 함수를 다음 then()에 넘겨준다.&#x20;

&#x20;예제 1은 값을 넘겨주는 것이기 때문에 2초 뒤 모든 then()의 결과 값이 출력 된다. 반면에 예제 2는 1, 2, 3초 뒤 각 then()의 값이 출력 된다.&#x20;

## 3. 실무에서 프로미스&#x20;

실제 웹 서비스에서 있을 법한 사용자 로그인 인증 로직에 프로미스를 여러 개 연결해보자.&#x20;

```javascript
getData(userInfo)
  .then(parseValue)
  .then(auth)
  .then(diaplay);
JsCopy
```

위 코드는 페이지에 입력된 사용자 정보를 받아와 파싱, 인증 등의 작업을 거치는 코드를 나타내었다. 여기서 `userInfo`는 사용자 정보가 담긴 객체를 의미하고, `parseValue`, `auth`, `display`는 아래와 같이 각각 a프로미스를 반환해주는 함수라고 가정한다.&#x20;

```javascript
var userInfo = {
  id: 'test@abc.com',
  pw: '****'
};

function parseValue() {
  return new Promise({
    // ...
  });
}
function auth() {
  return new Promise({
    // ...
  });
}
function display() {
  return new Promise({
    // ...
  });
}
JsCopy
```

이처럼 여러 개의 프로미스를 `.then()`으로 연결하여 처리할 수 있습니다.

## 4. 프로미스의 에러 처리&#x20;

### &#x20;4.1 Promise 객체에서 오류&#x20;

Promise 함수 내부에서 오류가 생겼을 경우 reject 함수가 실행되면서 catch()로 설정한 오류 처리가 실행된다.&#x20;

```javascript
function getData() {
  return new Promise(function(resolve, reject) {
    $.get('url 주소/products/1', function(response) {
      if (response) {
        resolve(response);
      }
      reject(new Error("Request is failed"));
    });
  });
}

// 위 $.get() 호출 결과에 따라 'response' 또는 'Error' 출력
getData().then(function(data) {
  console.log(data); // response 값 출력
}).catch(function(err) {
  console.error(err); // Error 출력
});
```

```javascript
function getData() {
  return new Promise(function(resolve, reject) {
    reject(new Error("에러에러에러에러!!!!!!!!!!"));
  });
}

getData().then(function(data) {
  console.log(data); // response 값 출력
}).catch(function(err) {
  console.error(err); // Error 출력
});
```

![](/files/-MXAgeG7sofk24f2XNJ4)

## 5. 참고&#x20;

{% embed url="<https://joshua1988.github.io/web-development/javascript/promise-for-beginners/>" %}

{% embed url="<https://www.youtube.com/watch?v=CA5EDD4Hjz4>" %}
