• 230214 TIL : 비동기 프로그래밍 (Promise)

    2023. 2. 15.

    by. 옛슬

    오늘은 비동기 프로그래밍에서 사용하는 Promise에 대해서 공부해보기로 했다.

    사실 요즘 코드를 봤을 때는 대부분 await/async로 작성되어있는거 같은데

    그래도 모르면 안될거 같아서 천천히 공부해 본다 🤔

     


    Promise

    - 우리나라말로 번역하면 말그대로 '약속'이라는 의미이다. Promise는 최종 결과를 리턴하는 것이 아니라 미래의 어떤 시점에 결과를 제공하겠다는 약속(Promise)를 반환한다.

    약속(Promise)을 반환한다는 말의 의미

    - 말그대로 어떤 시점의 결과를 제공하는데, 이는 프로미스의 3가지 상태를 통해 콜백함수가 호출된다.

    * Promise의 3가지 상태 : 대기 (pending) / 이행 (fulfilled) / 거부 (rejected)

    - 대기중인 Promise가 이행 혹은 거부될 때 then() 메서드에 의해 큐에 추가된 콜백함수가 호출된다. 

    - 즉, 프로미스를 반환한다는 의미는 어떤 상태를 반환한다는 의미이고 이를 통해 then()메서드를 통해 알맞은 콜백함수가 처리된다.

     

     

    - Promise는 비동기 작업의 최종 완료, 실패를 나타내는 객체이다.

    - Promise는 함수에 콜백을 전달하는 대신에, 콜백을 첨부하는 방식의 객체이다.

    // 콜백을 전달하는 방식
    function makeCoffee (name, sucess, fail) {
        const randomNum = Math.floor(Math.random() * 100);
        setTimeout(function () {
            if(randomNum % 2 === 0) {
                sucess(name);
            }else {
                fail(name);
            }
        },1000)
    };
    
    function makeTastyCoffee (name) {
        console.log(`${name} 커피가 성공적으로 만들어졌습니다!🥰`);
        return;
    };
    
    function makeHorribleCoffee (name) {
        console.log(`당신은 끔찍한 바리스타군요 😥, ${name} 커피 만들기는 실패하였습니다`);
        return;
    };
    
    makeCoffee('아메리카노',makeTastyCoffee,makeHorribleCoffee);
    
    
    // 콜백 첨부 방식
    function makeCoffee (name) {
        const randomNum = Math.floor(Math.random() * 100);
         return new Promise((resolve, reject) => {
            setTimeout(function () {
                if(randomNum % 2 === 0) {
                    resolve(`${name} 커피가 성공적으로 만들어졌습니다!🥰`);
                }else {
                    reject(`당신은 끔찍한 바리스타군요 😥, ${name} 커피 만들기는 실패하였습니다`);
                }
            },1000)
        })
    }
    
    makeCoffee('카페라떼').then(result => console.log(result));

    - 두번째 예시에 콜백을 첨부할 수 있는 이유는 makeCoffee()함수가 Promise를 반환하기 때문이다. 그리고 이를 비동기 함수 호출이라고 한다.

     

    비동기 함수 호출의 장점

    1. 콜백은 이벤트 루프가 콜스택이 빈 상태가 될 때까지는 절대 호출되지 않는다. (이는 then()을 이용한 추가 콜백도 적용된다)

    2. then()을 연달아 작성하여 콜백을 추가하는 경우 각각의 콜백은 주어진 순서대로 작동이 가능하다.

     

    비동기 작업이 순서대로 작동이 가능한 이유는 

    - promise chain을 이용하여 해결한다.

    - then() 함수는 새로운 promise를 반환한다.

    doSomething()
    .then(result => doSomethingElse(result))
    .then(newResult => doThirdThing(newResult))
    .then(finalResult => console.log(`Got the final result: ${finalResult}`))
    .catch(failureCallback);

    - 여기서 중요한 점은 promise chain시 반드시 반환값이 있어야 다음 프로미스를 처리할 수 있다. 

     

    Promise.prototype.then()

    - then() 메서드는 fulfilled 와 rejected 케이스의 프로미스 콜백함수를 반환 받을 수 있다.

    - 해당 콜백함수는 곧바로 값을 리턴할 수도 있고, 또 다른 프로미스를 반환할 수 있다. ( 또 다른 프로미스를 반환하면 상단에 작성한거 처럼 프로미스 체인을 통해 값을 도출해낸다)

    - 상단에 작성한 예시가 이러한 Promise를 반환하고 해당 콜백함수는 값을 리턴하기 때문에 그대로 가져와서 console.log()에 찍은것이다.

    - 내가 새로 알았던 점은 나는 then()은 성공 시에, catch()는 실패시 사용한다고 생각했는데 then()은 fulfill과 reject 콜백함수를 반환한다.

    - 이렇게 작성이 가능하다. then()을 통해 성공 혹은 실패 상태에 따라 다르게 값을 리턴할 수 있다. 

    - 이 예시의 경우 성공때는 '바리스타'라는 호칭을 넣고 실패의 경우 이름만 부르는 값을 리턴한다 🤣

     

    Promise.prototype.catch()

    - catch()는 사실상 then()에서 실패 방식만 빼놓은 메서드이다. Promise가 rejected될 때 해당 콜백함수가 호출된다.

     


    사실 예전에 배운적이 있어서 금방 배우겠다~ 라고 생각했는데 생각보다 오래걸렸다.

    그리고 Promise의 메서드가 생각보다 많은데 이거는 내일 공부하고 정리해보도록 ... 

     

    참고자료 (MDN)

    https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Using_promises

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then

    댓글