FE/JavaScript

[JavaScript] 콜백 지옥 (2)

m5n 2024. 10. 16. 22:52

Promise 객체의 등장

  • 문제점
    • 기존 콜백함수의 경우, 중첩해서 사용하게 되면 가독성이 매우 떨어짐 (콜백 지옥)
    • 좀 더 가독성이 좋은 방법은 없을까 ? -> Promise 객체의 등장
  • 특징
    • resolve, reject 함수를 인자로 갖는 함수를 인자로 가짐
    • then의 return 값 또한 Promise 객체임
    • resolve
      • 조건이 성공되었을 때 반환하는 콜백함수
      • then에서 전달해준 함수가 들어감
    • reject
      • 조건이 실패하였을 때 반환하는 콜백함수
      • catch에서 전달해준 함수가 들어감
// Resolve - 성공했을 때 반환하는 콜백함수
// reject - 실패했을 때 반환하는 콜백함수

// then 함수의 인자는 여기서 1개 -> 데이터 타입이 함수 -> 그 함수의 인자가 data
// then에서 전달해준 함수가 resolve로 들어감. 
// ** then 메소드의 호출 결과는 프로미스 객체임 **

// catch는 reject로 들어가고
// finally는 then이든 catch든 리턴된 놈이 들어감

new Promise((resolve, reject) => {
  if(1) {
    const value = 10;
    resolve(value);
  } else {
    const error = new Error('에러발생')
    reject(error);
  }
}).then(data => {
  console.log(data)
}).catch(err => {
  console.log(err)
}).finally(() => {
  console.log("종료")
})

 

 

Promise 객체의 이용

  • 가독성
    • runTask() 함수를 보면 이전 글의 콜백 지옥보다 가독성이 좋아진 것을 확인 가능함
    • 하지만 아직 익숙하지가 않음 ... -> 원래 쓰던 문법처럼 사용할 순 없을까 ?
      • async, await 키워드의 등장
// 1초 후에 실행하는 fastFunction, 데이터에 2를 곱함
function fastFunction(data) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const result = data * 2;
            console.log("fast function done", result)
            
            resolve(result);
        }, 1000)
    })
}

// 3초 후에 실행하는 slowFunction, 데이터에 10을 더함
function slowFunction(data) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const result = data + 10;
            console.log("slow fucntion done", result)

            resolve(result);
        }, 3000)
    })
}

// 2초 후에 실행하는 normalFunction, 데이터 2로 나눔
function normalFunction(data) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const result = data / 2;
            console.log("normal function", result)

            resolve(result);
        }, 2000)
    })
}

// 예제
// slow->fast->normal->slow

function runTasks() {
    slowFunction(10).then((data) => {   // then의 인자가 reslove로 들어간다. then의 리턴 값도 promise 객체다
        return fastFunction(data);
    }).then((data) => {
        return normalFunction(data);
    }).then((data) => {
        return slowFunction(data);      // 더이상 인자로 받은 reslove()가 없음 (.then이 없으니까)
    }).finally(() => {                  // -> finally()가 실행됨
        console.log("end");
    })
    
}

runTasks()