제로베이스
then 메소드 이해하기 본문
Promise 객체를 공부할 때 then 메소드에 대해서 확실히 알고 넘어가야 한다.
const successCallback = function () { };
const errorCallback = function () { };
fetch('https://jsonplaceholder.typicode.com/users') // Promise-A
.then(successCallback, errorCallback); // Promise-B
1. fetch 함수에서 리턴하는 Promise 객체를 Promise-A 객체라고 하고,
2. then 메소드가 리턴하는 Promise 객체를 Promise-B 객체하고 해본다.
그리고 fetch 함수의 작업이 성공하는 경우와 실패하는 경우 나누어서 생각해보자.
1. fetch 함수의 작업이 성공해서 Promise-A 객체가 fulfilled 상태가 된 경우 : then 메소드 안의 첫 번째 콜백인 successCallback이 실행된다.
2. fetch 함수의 작업이 실패해서 Promise-A객체가 rejected 상태가 된 경우 : then 메소드 안의 두번째 콜백인 errorCallback이 실행된다.
여기서 중요한 점은 Promise-B는 실행된 successCallback 또는 errorCallback에서 무엇을 리턴하는냐에 따라 그 상태(fulfilled or rejected) 와 결과 (작업성공 결과 or 작업 실패 정보)가 결정 된다는 점이다.
then 메소드가 리턴한 Promise 객체가 콜백이 리턴하는 값에 따라 어떻게 달라지는지를 잘 파악해야한다.
📍 실행된 콜백이 어떤 값을 리턴하는 경우
successCallback이 실행되든 errorCallback이 실행되든 실행된 콜백에서 어떤 값을 리턴하는 경우 아래 2가지 경우로 나눌 수 있다.
• Promise 객체인 경우
• Promise 객체 이외의 경우
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 객체가 콜백이 리턴한 Promise 객체의 상태와 결과를 똑같이 따라 갖게 된다. 즉 위 코드의 첫번째 then메소드가 리턴했던 Promise 객체는 response객체의 json 메소드가 리턴한 Promise 객체가 추후에 갖게 되는 상태와 결과를 그대로 따라서 갖게 된다는 뜻이다.
좀 더 편하게 기억하기 위해서는 그냥 콜백에서 리턴하는 Promise객체를 then 메소드가 그대로 리턴한다고 생각해도 좋다. 그럼 이제 그 다음부터는 콜백에서 리턴한 Promise 객체로부터 다시 Promise Chain이 쭉 이어져 나간다고 보면 된다.
Promise 객체 이외의 값을 리턴하는 경우
콜백이 꼭 Promise 객체만을 리턴하는건 아니다. 그냥 단순한 숫자, 문자열, 일반 객체 등을 리턴할 수 도 있다. 이런 경우에는 then 메소드가 리턴했던 Promise 객체는 fulfilled 상태가 되고 작업 성공 결과로 그값을 갖게 된다.
fetch('https://jsonplaceholder.typicode.com/users')
.then((response) => response.json(), (error) => 'Try again!')
.then((result) => { console.log(result) });
예를 들어, 지금 인터넷이 안되는 상황에서 이 코드를 실행했다고 해보자. 그럼 fetch 함수의 작업이 실패해서 두번째 콜백인 (error) => 'Try again!' 이 실행된다. 두번째 콜백은 'Try again!' 이라는 문자열을 리턴하고 있는데 이렇게하면 해당 콜백을 등록한 then 메소드가 리턴했던 Promise 객체가 fulfilled 상태가 되고 그 작업 성공 결과로 'Try again!' 문자열을 갖게 된다.
📍 실행된 콜백이 아무 값도 리턴하지 않는 경우
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를 갖게 된다.
실행된 콜백 내부에서 에러가 발생했을 때
콜백이 실행되다가 에러가 발생하는 경우가 있다.
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 상태가 되고 작업 실패 정보로 해당 에러 객체를 갖게 된다.
📍 아무런 콜백도 실행되지 않을 때
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 객체는 이전 Promise 객체와 동일한 상태와 결과를 갖게 된다. 그러니까 지금 Promise-2 객체는 Promise-1 객체처럼 rejected 상태가 되고 똑같은 작업 실패 정보를 갖게 된다.
그럼 rejected 상태가 된 Promise-2의 then 메소드에는 이제 두번째 콜백이 존재하기 때문에 그 두번째 콜백이 실행된다. 이렇게 아무런 콜백도 실행되지 않는 경우에는 이전 Promise 객체의 상태와 결과가 그대로 이어진다.
'웹 개발 기본기' 카테고리의 다른 글
async 함수가 리턴하는 Promise 객체 (0) | 2023.08.27 |
---|---|
catch 메소드 이해하기 (0) | 2023.08.27 |
비동기 실행 함수들 (0) | 2023.08.26 |
동기 실행과 비동기 실행 (0) | 2023.08.26 |
Status Code (0) | 2023.08.26 |