ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JavaScript] Promise란 무엇인가?
    Server/NodeJS 2020. 6. 25. 01:17
    728x90
    반응형

    저번 글에서 비동기 처리와 콜백함수에 대하여 간단히라도 공부하였다. 비동기 처리란 "특정 코드의 실행이 완료될 때 까지 기다리지 않고 다음 코드를 먼저 수행하는 자바스크립트의 특성"이다. 

    function task1() {
        setTimeout( () => {
            console.log("task1");
        }, 0);
    }
    
    function task2() {
        console.log("task2");
    }
    
    function task3() {
        console.log("task3");
    }
    
    task1();
    task2();
    task3();

    저번 글에서 setTimeout() 함수가 비동기 처리의 대표적인 예시라고 하였다. 위의 코드를 비동기의 개념을 모르고 출력결과를 예측해보라 한다면 아마도 task1 - task2 - task3 함수를 호출한 순서대로 대답을 할 것이다. 하지만 위의 코드는 순서대로 출력이 되지 않고 뒤죽박죽 섞여서 결과가 출력이 된다. 이러한 상황에서 흐름제어를 하기위해서 등장한 것이 바로 Promise 객체이다. 

     

     

    Promise에 대해 알아보자.

    new Promise(function(resolve, reject) {
        // logic
    });

    Promise는 위와 같이 new Promise() 메소드를 호출하여 콜백함수로 선언하는 것이 가능하다. 동작에 대한 결과를 올바르게 줄 수 있다면 resolve, 동작을 실패했다면 reject 함수를 호출한다. 다시 정리하자면, Promise는 약속이다. Promise의 객체가 then() 함수에 넘겨진 파라미터(함수)를 단 한번만 호출하겠다는 약속이라고 생각하면 된다. then()이 무엇인지 Promise에 대해 좀 더 자세히 정리해보자.

     

     

    프로미스의 3가지 상태

    프로미스를 사용할 때 알아야 하는 가장 기본적인 개념이 바로 프로미스의 처리과정이다. new Promise()로 프로미스를 생성하고 종료될 때 까지 3가지 상태를 갖는다.

     

    • Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
    • Fulfiled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
    • Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태

     

     

    Pending(대기)

    new Promise();

    위와 같이 new Promise() 메소드를 호출하면 대기(pending) 상태가 된다. 

    new Promise(function(resolve, reject) {
        // logic
    });

    위에서 말한 것과 같이 new Promise() 메소드를 호출하면 콜백함수를 사용이 가능하고 인자는 resolve, reject이다. 

    동작이 성공했다면 resolve 메소드를 호출한다 했는데 이렇게 되면 Fullfilled 상태가 된다.

     

     

    Fullfilled(이행)

    new Promise(function(resolve, reject) {
        resolve();
    });

    위와 같이 resolve()를 호출하게 되면 이행(Fullfilled) 상태가 된다. 

    function getData() {
        return new Promise((resolve, reject) => {
            var data = 100;
            resolve(data);
        })
    }
    
    getData().then(function(resolveData) {
        console.log(resolveData);
    });

    위와 같이 이행상태가 되었을 때 then()을 이용하면 처리 결과 값을 받을 수 있다.

     

     

    Rejected(실패)

    new Promise(function(resolve, reject) {
        reject();
    });

    위와 같이 reject()를 호출하게 되면 실패(Fullfilled) 상태가 된다. 그리고 이번에는 실패가 되면 실패한 이유를 catch()를 통해서 받을 수 있다. 

    function getData() {
        return new Promise((resolve, reject) => {
            reject(new Error("Request is failed"));
        });
    }
    
    getData().then().catch((err) => {
        console.log(err);
    });

     

     

    여러개의 프리미스 연결하기 (Promise Chaining) 

    프로미스의 또 다른 특징은 여러 개의 프로미스를 연결하여 사용할 수 있다는 점이다. then() 메소드를 호출하고 나면 새로운 프로미스 객체가 반환이 된다. 아래와 같이 사용할 수 있다는 것을 참고하자.

    const func1 = (param) => {
        return new Promise((resolved, rejected) => {
            setTimeout(() => {
                console.log('func1 return resolved');
                resolved(`func 1 success: ${param}`);
            }, 500);
        });
    }
    
    const func2 = (param) => {
        return new Promise((resolved, rejected) => {
            setTimeout(() => {
                    console.log('func2 return rejected');
                    rejected(new Error(`func2 param: '${param}'`));
                }, 500);
        });
    }
    
    const func3 = (param) => {
        return new Promise((resolved, rejected) => {
            setTimeout (() => {
                    console.log('func3 return resolved');
                    resolved(`func 3 success: ${param}\n`);
                }, 500);
        });
    }
    
    const func4 = (param) => {
        return new Promise((resolved, rejected) => {
            setTimeout(() => {
                    console.log('func4 return rejected');
                    rejected(Error(`func 4 error: ${param}\n`));
                }, 500);
        });
    }
    
    const func5 = (param) => {
        return new Promise((resolved, rejected) => {
            setTimeout(() => {
                    console.log('func5 return resolved');
                    resolved(`func 5 success: ${param}\n`);
                }, 500);
        });
    }
    
    const promise = func1('sopt')
    
    
    promise
        .then(func2)
        .then(func3)
        .catch(console.error) // errorhandler1
        .then(func4)
        .then(func5)
        .catch(console.error) // errorhandler2
        .then(console.log);
        
    

     실행과정은 처음에 fuc1 -> func2(에러발생) -> func3를 생략하고 바로 catch로 넘어감 -> func4(에러발생) -> catch문으로 가게 된다. 

     

     

     

    Reference

    https://joshua1988.github.io/web-development/javascript/promise-for-beginners/

     

    반응형

    댓글

Designed by Tistory.