Basic - promise.then( )

1day2coffee·2021년 8월 20일
0
post-thumbnail

이번에는 then 메소드가 리턴한 Promise 객체가, 콜백이 리턴하는 값에 따라 어떻게 달라지는지 경우를 나누어서 다뤄보겠다.

const successCallback = function () { };
const errorCallback = function () { };

fetch('https://jsonplaceholder.typicode.com/users') // Promise-A
  .then(successCallback, errorCallback); // Promise-B

일단, 이 코드에서

fetch 메소드가 리턴하는 Promise 객체를 Promise-A 객체라고 하고,
then 메소드가 리턴하는 Promise 객체를 Promise-B 객체라고 하자.

AND

  • fetch 작업이 성공해서 Promise-A 객체가 fulfilled 상태가 된 경우 : then "첫 번째" 콜백인 successCallback이 실행된다.

  • fetch 작업이 실패해서 Promise-A 객체가 rejected 상태가 된 경우 : then "두 번째" 콜백인 errorCallback이 실행된다.

여기서 중요한 점은 Promise-B는, 실행된 successCallback 또는errorCallback에서 무엇을 리턴하느냐에 따라

상태(fulfilled or rejected)결과(작업 성공 or 작업 실패)가 결정된다는 점이다.


1. 실행된 콜백이 어떤 값을 리턴하는 경우

successCallback 이든지 errorCallback이든지, 실행된 콜백에서 어떤 값을 리턴하는 경우이다.

(1) Promise 객체를 리턴하는 경우

fetch('https://jsonplaceholder.typicode.com/users')
  .then((response) => response.json())
  .then((result) => { console.log(result) });

위 코드에서 (response) ⇒ response.json() 이 콜백은 Promise 객체를 리턴하는 코드이다. 또 response 객체의 json 메소드가 Promise 객체를 리턴한다.

이렇게 콜백에서 Promise 객체를 리턴하는 경우에는 위 코드의 첫 번째 then 메소드가 리턴했던 Promise 객체는, response 객체의 json 메소드가 리턴한 Promise 객체가 추후에 갖게 되는 상태와 결과를 그대로 따라서 갖게 된다.

좀 더 편하게 기억하기 위해서는 그냥 콜백에서 리턴하는 Promise 객체를 then 메소드가 그대로 리턴한다고 생각하셔도 됩니다. 그럼 이제 그 다음부터는 콜백에서 리턴한 Promise 객체로부터 다시 Promise Chain이 쭉 이어져 나간다고 보면 되죠.

(2) Promise 객체 이외의 값을 리턴하는 경우

콜백이 단순한 숫자, 문자열, 일반 객체 등을 리턴할 수도 있다. 이런 경우에 then 메소드가 리턴했던 Promise 객체는 fulfilled 상태가 되고 작업 성공 결과로 그 값을 갖게 됩니다.

// Internet Disconnected

fetch('https://jsonplaceholder.typicode.com/users')
  .then((response) => response.json(), (error) => 'Try again!')
  .then((result) => { console.log(result) });

인터넷이 안 되는 상황에서 이 코드를 실행했다고 하자. 그럼 fetch 작업이 실패해서 두 번째 콜백인 (error) ⇒ 'Try again!' 이 실행된다. 이렇게 하면 해당 콜백을 등록한 then 메소드가 리턴했던 Promisefulfilled 상태가 되고, 그 작업 성공 결과로 'Try again' 문자열을 갖게 된다.


2. 실행된 콜백이 아무 값도 리턴하지 않는 경우

// Internet Disconnected

fetch('https://jsonplaceholder.typicode.com/users')
  .then((response) => response.json(), (error) => { alert('Try again!'); })
  .then((result) => { console.log(result) });

콜백이 무언가를 리턴하는 게 아니라 단순히 alert 함수만 실행하고 끝난다고 하자. 그럼 이 콜백은 아무런 값도 리턴하지 않은 것과 같다. 자바스크립트에서는 함수가 아무것도 리턴하지 않으면 undefined를 리턴한다. 따라서 then 메소드가 리턴했던 Promise 객체는 fulfilled 상태가 되고, 그 작업 성공 결과로 undefined를 갖게 된다.


3. 실행된 콜백 내부에서 에러가 발생했을 때

fetch('https://jsonplaceholder.typicode.com/users')
  .then((response) => { 
        ...
        add(1, 2); // ReferenceError 발생
        ... 
  });

이렇게 정의하지도 않은 함수를 콜백에서 사용해서 에러가 발생하거나

fetch('https://jsonplaceholder.typicode.com/users')
  .then((response) => { 
        ...
        throw new Error('failed'); 
        ... 
  });

인위적으로 throw 문을 써서 에러를 발생시키는 경우이다.

이렇게 콜백 실행 중에 에러가 발생하면 then 메소드가 리턴한 Promise 객체는 rejected 상태가 되고, 그 작업 실패 정보로 해당 Error 객체를 갖게 된다.


4. 아무런 콜백도 실행되지 않을 때

// Internet Disconnected

fetch('https://www.google.com') // Promise-1
  .then((response) => response.text()) // Promise-2
  .then((result) => { console.log(result) }, (error) => { alert(error) });

then 메소드의 아무런 콜백도 실행되지 않는 경우가 있다. 인터넷을 끊고 나서 위 코드를 실행했다고 하자. 그럼 fetch 함수가 리턴한 Promise-1 객체는 rejected 상태가 되기 때문에, 첫 번째 then 메소드의 두 번재 콜백이 실행되어야 한다. 그런데 두번째 콜백이 없으므로 아무런 콜백도 실행되지 않는다.

이런 경우에 then 메소드가 리턴한 Promise-2 객체는 어떻게 될까? then 메소드가 리턴했던 Promise-2 객체는, 이전 Promise 객체와 동일한 상태와 결과를 갖게 된다. 그러니까 지금 Promise-2 객체는 Promise-1 객체처럼 rejected 상태가 되고, 똑같은 작업 실패 정보를 갖게 된다.

그럼 rejected 상태가 된 Promise-2의 then 메소드에는 이제 두 번째 콜백이 존재하기 때문에 그 두 번째 콜백이 실행된다.

profile
깊이생각하고 한삽질뜨는

0개의 댓글