javascript | Promise, .then 기초 정리

하영·2024년 6월 13일
0

JavaScript

목록 보기
9/29

콜백함수도 어려웠는데 Promise 도 끙끙거렸다.
콜백함수 - Promise - Async/Await 으로 쭉쭉 뻗어나가는데 점점 동태눈이 되어가는 나 O_O?
차근차근 기초부터 정리해야할 것 같아서 오늘은 Promise 완전 기초부분을 확실히 정리해보려 한다.

Promise

Promise비동기 처리에 이용되는 객체이다.
비동기 연산이 종료된 이후 결과 값, 에러가 나면 실패한 값을 처리하는 처리기를 연결할 수 있다.
단, 최종 결과를 반환하는 것이 아닌!! 미래 어떤 시점에 결과를 제공하겠다는 Promise 를 반환한다.

  • 비동기처리란? 특정 코드 실행이 완료될 때까지 기다리지 않고 다음 코드를 먼저 수행해버리는 것으로 자바스크립트의 특성이다.

열심히 mdn을 긁어보았구욤?
무슨 느낌인지는 알았으니 유데미에서 본 코드 + 구글링 한 코드들 보면서 이해해보자.

본격적으로 코드를 보기 전에 Promise 가 가지고 있는 상태는 3가지이다.

  • pending : 아무것도 하지 않은 초기 상태
  • fulfilled : 연산이 성공했을 때 (resolve)
  • rejected : 연산이 에러(실패)났을 때 (reject)

Promise 객체는 아래 코드처럼 만든다.

let promise = new Promise(function (resolve, reject) {
  // 코드 (executor)
}                 
                          
// ** 화살표 함수 버전                 
let promise = new Promise((resolve, reject) => {
  // 코드 (executor)
}

인수 resolve, reject 는 자바스크립트에서 제공하는 콜백이다.

resolve(value) reject(error) 처럼 반드시 인수를 넘겨준 콜백 중 하나를 호출해야한다.

성공하면 resolve(value) // 실패하면 reject(error)

간단한 코드와 유데미 강의에서 본 코드를 살펴보자

let promise = new Promise(function(resolve, reject) {
  // 1초 뒤에 일이 성공적으로 끝났다는 신호가 전달되면서 result는 '완료'가 됩니다.
  setTimeout(() => resolve("완료"), 1000);
}
  1. Promise 를 만들면서 resolvereject 인자도 만들었다.
  2. setTimeout() 함수가 실행되게 하고 1초 뒤에 성공하면 resolve("완료")가 뜬다.

Promise가 아무것도 안 되었을 때 (성공도 실패도 안 함) => pending 상태로 나타나고
성공(resolve) 하면 => fulfilled 상태가 나올 것이다.
(위 예시는 에러가 발생했을 때를 만들지 않았다.)


let promise = new Promise(function(resolve, reject) {
  setTimeout(() => reject(new Error("에러 발생!")), 1000);
}

위 코드의 경우에는 reject 가 호출되면 rejected 로 변하게 된다.

Promise가 아무것도 안 되었을 때 (성공도 실패도 안 함) => pending 상태로 나타나고
에러(reject) 나면 => rejected 상태가 나올 것이다.

⭐️ Promise 는 성공 또는 실패만 하기 때문에 resolve가 호출되면 reject는 무시되고, 반대로 reject가 호출되면 resolve는 무시된다.




유데미 강의 코드

위에서 본 코드와 비슷하게 생겼지만 조금 더 복잡하게 보일 수 있다.

  1. fakeRequestPromise 라는 함수를 만들고 Promise를 이용해 값을 반환한다.
  2. setTimeout() 함수를 실행시키는데 조건문으로 성공과 실패를 반환할 것.
  3. delay가 일정시간 이상 걸리면 reject로 변환되어 'Connection Timeout :(' 가 나옴.
  4. delay가 일정시간 이하로 빠르게 나온다면 fulfilled (resolve)로 변환되어 'Here is your fake data from + url 주소' 가 나옴.

✅ 콘솔창으로 확인

  1. 성공했을 때
  1. 실패했을 때

(음 근데 왜 pending으로 찍힐까.. 이건 더 공부해보자...ㅎ)



.then, .catch

같이 알아야하는 중요한 메서드!

promise.then(
  function(result) {},
  function(error) {}
);

result 인수는 성공했을 때 실행되는 함수이고 error 는 실패했을 때 실행되는 함수이다.


이것도 예시로 이해해보자

let promise = new Promise(function(resolve, reject) {
  setTimeout(() => reject(new Error("에러 발생!")), 1000);
}
                          
                          
promise.then(
  result => alert(result), // 실행되지 않음
  error => alert(error) // 1초 후 "Error: 에러 발생!"을 출력
);

에러가 발생하는 코드를 작성했다면
아래에 있는 .then 은 거부한 두번째 (error)가 담긴 경고창을 띄운다.

이렇게 에러가 발생할 때 .catch 를 활용해서 에러가 발생했을 때 어떤 문구가 console에 뜨게 해달라는 등의 코드도 작성할 수 있다.


+ 유데미 강의코드로 복습하기

const request = fakeRequestPromise('yelp.com/api/coffee');

request // 객체
    .then(() => { // 메서드
        console.log('promise resolved')
        console.log('it worked')
    })
    .catch(() => { // 메서드
        console.log('promise rejected')
        console.log('error')
    })

앞서 봤던 코드와 비슷하나 then, catch 메소드를 활용하여 깔끔해졌다.

fakeRequestPromise('yelp.com/api/coffee/page1')
    .then((data) => {
        console.log('it worked!! (page1)')
        console.log(data)
        return fakeRequestPromise('yelp.com/api/coffee/page2')
    })
    .then((data) => {
        console.log('it worked!! (page2)')
        console.log(data)
        return fakeRequestPromise('yelp.com/api/coffee/page3')
    })
    .then((data) => {
        console.log('it worked!! (page3)')
        console.log(data)
    })
    .catch((err) => {
        console.log('ERROR!!!')
        console.log(err)
    })

최종적으로 Promise까지 활용하여 코드를 완성했다.
page1 이 성공적으로 불러와지면 > page2가 나오고 > page3이 출력된다.
그렇지 않을 때는 error로 변환된다.

Promise를 사용하면 실패할 때마다 catch메소드를 쓰지 않고 마지막에 한번만 적어도 되기 때문에 편하고 보기도 좋다.

위에 있는 콘솔창은 3개가 모두 잘 변환되었을 때이고
아래는 에러가 발생한 경우이다.



+ .then 메소드 조금 더 살펴보기

const delayedColorChange = (color, delay) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            document.body.style.backgroundColor = color;
            resolve();
        }, delay)
    })
}
delayedColorChange('tomato', 1000)
    .then(() => {
        return delayedColorChange('orange', 1000)
    })
    .then(() => {
        return delayedColorChange('yellow', 1000)
    })
    .then(() => {
        return delayedColorChange('green', 1000)
    })
    .then(() => {
        return delayedColorChange('indigo', 1000)
    })

reject는 따로 작성하지 않아서 resolve만 되는 코드이다.
(이 경우라면 resolve만 썼어도 됐을 듯..!)

성공적으로 처리되는 경우만 다루고 싶은 경우에는 then에 인수를 하나만 전달하면 된다.
따라서 위 코드는 1초마다 색이 바뀌게 된다.


아직 Async, await까지 남아있다는게 공포다.
한번에 이해가 된다거나... 완전히 내꺼가 됐다!! 하는 느낌이 안 들어서 반복해서 듣고 여러 예시 코드들을 보면서 익숙하게 만들어야겠다.




출처

profile
왕쪼랩 탈출 목표자의 코딩 공부기록

0개의 댓글

관련 채용 정보