ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [NodeJS] Promise, Await
    NodeJS/Basic 2022. 9. 14. 17:29

    함수와 비슷한 기능을 갖고 있는 객체. 객체 내의 익명함수의 내용을 실현하고 결과를 보관하고 있다가 결과가 필요할 때 전달 받아 사용할 수 있게 해주는 구조의 객체

    // const pm = new Promise(/*익명함수*/);  // promise 객체의 전달인수 없는 선언문
    // 익명함수 한개를 품고 있는 객체 생성 & 객체 변수에 저장
    // promise 객체는 생성자의 전달인수로 익명함수를 전달하여야 생성되는데 
    // 이 익명함수는 promise의 기능이기도 함
    
    // func = (resolve, reject) => {}
    // const pm = new Promise(func); 
    // 또는 const pm = new Pormise((resolve, reject)=>{});
    
    // 전달인수로 전달되는 익명함수의 내용
    // const condition = true;
    // (resolve, reject) => {
    //     if(condition) resolve('성공'); // 괄호가 붙어서 함수처럼 호출
    //     else reject('실패');
    // }
    let condition = true;
    const pm = new Promise(
        (resolve, reject)=>{
            if(condition){
                resolve('성공');
            } else{
                reject('실패');
            }
        }
    );
    // 결과 처리 이전에 다른 코드가 작성될 수 있음
    console.log('1'); console.log('2'); console.log('3');
    // 이제 결과를 이용한 작업 시작
    // then과 catch와 finally에 익명함수가 전달인수로 전달되어 실행되게 함
    // -Resolve(성공리턴 값) -> then으로 연결
    // -Reject(실패리턴 값) -> catch로 연결
    // -finally -> 성공과 실패 리턴값에 상관없이 무조건 실행되는 영역
    pm
    .then(
        (message)=>{
            console.log(message); // resolve가 호출된 경우 실행
        }
        // (message)=>{}: resolve가 호출되어 도착했을 때 실행될 익명함수. message 변수에 '성공' 전달
    )
    .catch(
        (error)=>{
            console.error(error); // reject가 호출된 경우 실행
        }
        // (error)=>{}: reject가 호출되어 도착했을 때 실행될 익명함수. reject 변수에 '실패' 전달
    )
    .finally(
        ()=>{
            console.log('무조건 실행');
            // 성공실패 중 하나와 함께 반드시 실행
        }
    );
     
    // promise를 사용하지 않았을 때(동기식으로 무언가를 실행 => 비동기명령 삽입)
    const printString = (string, callback) => {
        var k = Math. floor(Math.random()*1000) +1; // 0~9초 사이의 랜덤한 시간 계산(밀리초)
        setTimeout(()=>{
            console.log(string+' '+k);
        }, k); // setTimeout: 지정한 시간(k)만큼 딜레이된 후 익명함수 실행(비동기함수)
        callback();
    }
    // printString( 'A',()=>{printString("B",function(){});} );
    printString( 'A',()=>{printString("B",()=>{});} );
     
    // 동기실행의 예(동기실행을 비동기 실행처럼 보이게 하기 위해 억지로 코드를 구현)
    console.log('작업 시작');
    console.log('작업1: 오래걸림');
    const wakeUpTime = Date.now() + 3000; // 현재시간에 3초를 더한값을 wakeUpTime 변수에 저장
    while(Date.now()<wakeUpTime){}
    // 오래 걸리는 작업이 오래 걸리는 것처럼 보이게 하기 위해 일부러 시간을 이용한 반복실행을 사용
    // 계속해서 현재시간을 wakeUpTime과 비교해서 그보다 커질때까지 반복실행
    console.log('작업1 종료');
    console.log('작업2: 오래걸리는 작업의 다음작업');
    console.log('작업2 종료');
    // 동시 실행은 완성할 수 없으며 동시 실행인 것처럼 비동기인 것처럼 코드를 꾸밀 수는 있음
    console.log('결론: 작업1, 작업2 순서에 맞춰 작업 종료');

     

    // 비동기 실행
    function longRunningTash(){
        console.log('작업1의 내용 모두 종료 후 끝');
    }
    console.log('시작');
    console.log('작업1: 오래걸리는 작업 시작');
    console.log('작업1을 비동기 실행으로 전환');
    setTimeout(longRunningTash, 3000); // setTimeout이 3초 후에 longRunningTash 함수를 호출함
    // setTimeout은 비동기함수이기 때문에 별도의 실행스레드가 실행을 담당.
    // 현재스레드는 다음 명령으로 실행포커스가 이동함
    console.log('작업2: 오래 걸리는 작업의 다음 작업 시작');
    console.log('작업2만 일단 끝');

     

    console.log('시작');
    let longRunningTash = new Promise(
        (resolve,reject)=>{
            console.log('작업1: 오래걸리는 작업시작');
            setTimeout(()=>{console.log('작업1: 종료');},3000);
            resolve();
        }
    );
    console.log('딴짓');console.log('딴짓');console.log('딴짓');
    longRunningTash
        .then(
            ()=>{
                console.log('작업2: 오래걸리는 작업의 다음작업');
                console.log('작업2: 종료');
            }
        );

     

    console.log('시작');
    let longRunningTash = new Promise(
        (resolve,reject)=>{
            console.log('작업1: 오래걸리는 작업시작');
            setTimeout(()=>{console.log('작업1: 종료');},3000);
            resolve();
        }
    );
    var k = Math.floor(Math.random()*1000) + 1;
    const wakeUpTime = Date.now() + 3000;
    while(Date.now()<wakeUpTime){}
    longRunningTash
        .then(
            ()=>{
                console.log('작업2: 오래걸리는 작업의 다음작업');
                console.log('작업2: 종료');
            }
        );

    EX) 홀수, 짝수 출력

    const k = 25;
    const pm = new Promise(
        (resolve, reject)=>{
            if(k%2==0){ resolve('짝수입니다');
            } else{ reject('홀수입니다');
            }
        }
    );
    pm
    .then( (message)=>{ console.log(message); } )
    .catch( (error)=>{ console.error(error); } )

    printString

    const printString =(string)=>{
        return new Promise((resolve, reject)=>{
            var k = Math.floor(Math.random()*1000)+1; // 램덤시간 생성
            console.log('비동기실행 시작');
            console.log('동기실행 시작');
            setTimeout(()=>{ // 생성시간 후 화면에 전달된 String 데이터를 출력
                console.log(string+' '+k);
                console.log('비동기실행 종료');
            }, k);
            resolve(); 
            // 비동기 실행 시작후 동기 실행으로 resolve() 호출
            // -> then 안에 있는 ()=>{} 익명함수 실행
        });
    }
    // promise 객체 생성 시 익명함수 안에 reject 함수 호출이 없다면 .catch 생략
    printString("A").then( ()=>{
        console.log('동기실행 종료');
    } );
    
    // 리턴된 promise 객체를 변수에 저장하지 않고 바로 then과 catch로 처리
    // printString("A").then().catch(); 
    
    /* 
    함수의 리턴값이 promise 객체에서 그 객체를 저장한 변수로 then과 catch 처리
    let p = printString("A");
    p
        .then()
        .catch();
    */
     

     

    연속 Promise()의 then과 resolve 사용

    const pm1 = new Promise((resolve, reject)=>{
        resolve("first resolve");
    });
    pm1.then((msg)=>{
        var k = Math.floor(Math.random()*1000)+1;
        setTimeout(()=>{
            console.log(msg);
        }, k);
        return new Promise((resolve, reject)=>{
            resolve("second resolve");
        });
    }).then((msg)=>{
        console.log(msg);
        return new Promise((resolve, reject)=>{
            resolve("third resolve");
        });
    }).then((msg)=>{
        console.log(msg);
    }).catch((error)=>{
        console.error(error);
    })


    Promise 결과를 별도의 함수 안에서 활용할 때 많이 사용하는 방법

     

    await

    -promise의 비동기 실행 결과를 필요할 때 꺼내쓰기 위한 키워드. 함수 안에서 promise 결과를 사용해야 한다면 반드시 써야하는 키워드

    const condition = true;
    const promise1 = new Promise((resolve, reject)=>{
        if(condition) resolve('success');
        else reject('failure');
    });
    
    // await를 사용한 명령은 반드시 async로 만들어진 함수 안에서 사용해야 함
    async function abcd(){
        try{
            const result = await promise1; // promise1 객체를 result 변수에 저장
            // 
            console.log('1', result);
            // await promise로 결과를 꺼냈다는건 resolve가 보내준 "success"을 꺼낸것이고
            // 그 과정에서 오류가 발생하면 reject가 보내준 "failure" error 변수에 빋음
        }catch(error){
            console.error('2'+error);
            // console.error의 error 함수는 log 함수와 기능이 같으며 주로 오류내용을 출력할 때 사용
        }
    }
    abcd();

    await promise의 연속 실행

    const promise = new Promise((resolve, reject)=>{
        resolve('first resolve');
    });
    async function func01(){
        try{
            const result = await promise;
            console.log( result);
            return "second resolve"; // new Promise 객체에 resolve 호출
        }catch(err){
            console.error(err);
        }
    }
    func01()
        .then((result)=>{console.log(result);})
        .catch((error)=>{console.error(error);});

    'NodeJS > Basic' 카테고리의 다른 글

    [NodeJS] Arrow Function  (0) 2022.09.14
    [NodeJS] Array  (0) 2022.09.14
    [NodeJS] Object  (0) 2022.09.14
    [NodeJS] var, const, let, template string  (0) 2022.09.14
    [NodeJS] 설치, 콘솔실행  (0) 2022.09.14

    댓글

Designed by Tistory.