ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Javascript] 콜백지옥을 해결할 수 있는 Promise
    IT&컴퓨터공학/Javascript 2021. 1. 21. 15:07

    Promise

    : 콜백함수로 비동기 처리를 하는 경우 앞에서 살펴봤듯이 콜백지옥이 만들어져 가독성이 떨어지고 디버깅하는데 어려움이있다. 때문에 등장한게 바로 Promise 다 !

     

    Promise 는 콜백함수를 대신하여 비동기를 간편하게 처리할 수 있도록 도와주는 자바스크립트 객체다.

     

     const promise = new Promise( (resolve,reject) => {
        // 네트워크 통신, 파일을 읽어오는 등의 heavy 한 작업들은
        // 동기적으로 작업하면 밑에 코드가 실행이 안돼서 시간이 오래걸리므로
        // 비동기적으로 구현해야한다
    
        console.log('doing something...');
     });

    이렇게 코드를 구현하면 콘솔에 'doing something' 이 출력되는데 , 

    즉 , Promise 는 구현하는 순간 바로 실행되기 때문에 ,

    만약 특정 사건이 발생되었을때만 ( ex) 버튼을 눌렀을때 ) 실행하고싶으면 이렇게 작성하면 X

     

     

    Promise State

    • 대기(pending) : 처리 로직이 아직 완료되지않은 상태
    • 이행(fullfilled) : 연산이 성공적으로 완료된 상태
    • 거부(rejected) : 연산이 실패한 상태

     

    pending

    new Promise();

    - new Promise() 메서드를 호출하면 Pending 상태가 된다.

    //일반함수 사용
    new Promise( function(resolve,reject){
    
    });
    
    
    //화살표함수 사용
    new Promise( (resolve,reject)=>{
    
    });
    

    - new Promise() 메서드 호출 시 콜백함수를 선언할 수있으며, 콜백함수의 인자는 resolve, 와 reject 이다.

     

    Fulfilled

    new Promise( (resolve,reject) => {
     resolve();
    });

    - 콜백함수의 인자 resolve 를 위처럼 실행하면 fulfilled 상태가 된다.

    function getData(){ // getData 라는 함수는 Promise 를 리턴한다.
        return new Promise((resolve,reject)=>{
            var data = 100;
            resolve(data); // 성공시 데이터를 넘긴다
        });
    }
    
    
    getData().then( resolveData => console.log(resolveData));

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

     

    Rejected

    function getData(){
        return new Promise((resolve,reject)=>{
            reject( new Error('error...')); // reject 를 호출하면 실패 상태가 된다
        });
    }
    
    
    getData()
        .then()
        .catch( (err) => console.log(err));

    - 실패 처리의 결과값은 catch() 로 받을 수 있다.

     

     

    https://www.youtube.com/watch?v=3Ao3OroqQLQ

     

    Producer 와 Consumer

     //1. Producer
    
     const promise = new Promise( (resolve,reject) => {
        setTimeout( ()=>{
             resolve('coding');
             //reject(new Error('error...'))
        },2000);
     });
    
    
     //2. Consumer : then, catch, finally 이용
    
     promise
        .then( (value) => { // promise 가 잘실행된경우
            console.log(value);
        })
        .catch(error => { // 에러가 발생했을때
            console.log(error);
        })
        .finally( () =>{ // 성공여부와 상관없이 마지막에 항상 실행
            console.log('finally');
        })
    
     

     

    • 동기적으로 진행 : Promise chaining 사용. 즉 , then() 여러개를 계속 이어붙여서 여러개의 promise 연결
    const f1 = (message) => {
        return new Promise( (res,rej)=> {
            setTimeout(()=>{
                res("1번 주문 완료");
            },3000);
        })
    }
    
    const f2 = (message) => {
        console.log(message);
        return new Promise( (res,rej)=> {
            setTimeout(()=>{
                res("2번 주문 완료");
            },2000);
        })
    }
    
    const f3 = (message) => {
        console.log(message);
        return new Promise( (res,rej)=> {
            setTimeout(()=>{
                res("3번 주문 완료");
            },1000);
        })
    }
    
    f1()
        .then( (res) => f2(res) )
        .then( (res) => f3(res) ) 
        .then( (res) => console.log(res) ) // f3 의 res 를 출력
        .catch()
        .finally( ()=>{ console.log('끝')} );

     

    • 비동기적으로 진행 : Promise.all( [    ] )  / Promise.race( [   ] ) 사용
    const f1 = () => {
        return new Promise( (res,rej)=> {
            setTimeout(()=>{
                res("1번 주문 완료");
            },3000);
        })
    }
    
    const f2 = (message) => {
        console.log(message);
        return new Promise( (res,rej)=> {
            setTimeout(()=>{
                res("2번 주문 완료");
            },2000);
        })
    }
    
    const f3 = (message) => {
        console.log(message);
        return new Promise( (res,rej)=> {
            setTimeout(()=>{
                res("3번 주문 완료");
            },1000);
        })
    }
    
    console.time("x");
    Promise.all([f1(),f2(),f3()]).then( (res)=>{ // f1,f2,f3을 한번에 시작할때 사용
        console.log(res);
        console.timeEnd("x");
    })

    - Promise.all 의 경우 f1, f2, f3 이 다 끝날때까지 기다린다. 위의 코드에서는 3초가 걸린다

     

    console.time("x");
    Promise.race([f1(),f2(),f3()]).then( (res)=>{
        console.log(res);
        console.timeEnd("x");
    })

    - Promise.race 의 경우 f1, f2 ,f3 중 하나라도 끝나면 바로 출력한다. 때문에 위의 코드에서는 1초가 걸린다

    댓글

Designed by Tistory.