-
[Javascript] 콜백지옥을 해결할 수 있는 PromiseIT&컴퓨터공학/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() 로 받을 수 있다.
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초가 걸린다
'IT&컴퓨터공학 > Javascript' 카테고리의 다른 글
[Javascript] if 문으로 undefined / null 체크 방법 (0) 2021.01.23 [Javascript] async 와 await (0) 2021.01.22 [Javascript] callback 함수와 callback 지옥 (0) 2021.01.21 [Javascript] var 변수의 특징과 const, let 의 차이점 (0) 2021.01.18 [Javascript] 화살표 함수 와 일반 함수 (0) 2021.01.18 댓글