-
[NodeJS] Promise, AwaitNodeJS/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