본문 바로가기
JavaScript

Promise

by 융디's 2024. 4. 21.
728x90
Promise

Promise

@2024.04.04

Promise 함수

💡
ES6에 도입된 기능으로, 자바스크립트 객체 중 하나
  • Promise는 비동기 작업의 성공 혹은 실패를 나타낸다.
  • 비동기 작업의 개수가 많아져도 코드의 깊이가 깊어지지 않는다.
  • 단점
    • 에러를 잡을 때 몇 번째에서 발생했는지 알아내기 어렵다.
    • 특정 조건에 따라 분기를 나누는 작업도 어렵다.
    • 특정 값을 공유해가면서 작업을 처리하기도 까다롭다
  • 단점은 async/await를 사용하면 해결 가능

콜백 지옥

💡
비동기 작업이 많아질 경우 코드의 깊이가 계속 깊어지는 현상
  • 함수 계속 중첩되어 가독성이 떨어진다.
  • 코드의 복잡성이 증가하여 유지 보수가 어려워진다.
  • 예시
    • 숫자 n을 파라미터로 받아와 다섯 번에 걸쳐 1초마다 1씩 더해서 출력
    function increaseAndPrint(n, callback) {
    	setTimeout(() => {
    		const increased = n + 1;
    		console.log(increased);
    		if (callback) {
    			callback(increased);
    		}
    	}, 1000);
    }
    increaseAndPrint(0, n => {
    	increaseAndPrint(n, n => {
    		increaseAndPrint(n, n => {
    			increaseAndPrint(n, n => {
    				increaseAndPrint(n, n => {
    					console.log('끝!');
    				});
    			});
    	});
    });

Promise 만들기

💡
Promise 객체는 생성자 함수를 사용하여 생성된다.
  • 생성자 함수는 하나의 인자를 받으며, 이 인자는 비동기 작업을 수행하는 함수다.
  • 이 함수는 두 개의 매개변수(resolve, reject)를 가진다.
    • 비동기 작업이 성공하면 resolve를 호출하여 작업 결과를 반환
    • 실패하면 reject를 호출하여 에러를 반환한다.
  • Promise 객체가 가지는 세 가지 상태
    • 대기 : 비동기 작업이 아직 완료되지 않은 상태
    • 이행 : 비동기 작업이 성공적으로 완료된 상태
    • 거부 : 비동기 작업이 실패한 상태

Promise 예시

  • 1초 뒤에 성공시키는 상황 구현
    // Promise 객체 생성 
    // resolve 함수를 호출하여 Promise를 성공 상태로 변경 
    const myPromise = new Promise((resolve, reject) => {
    	setTimeout(() => {
    		resolve(1);
    	}, 1000);
    });
    myPromise.then(n => {
    	console.log(n); // 1
    });
    • resovle를 호출할 때 특정 값을 파라미터로 넣어주면, 이 값을 작업이 끝나고 나서 사용 가능
    • 작업이 끝나고 또 다른 작업을 할 때 Promise 객체뒤에 .then()을 붙여서 사용하면 된다.
  • 1초 뒤에 실패하는 상황 구현
    const myPromise = new Promise((resolve, reject) => {
    	setTimeout(() => {
    	// reject 함수를 호출하여 Promise를 실패 상태로 변경 
    	reject(new Error());
    	}, 1000);
    });
    myPromise
    //Promise가 성공적으로 resolve된 경우의 동작을 정의
    	.then(n => {
    		console.log(n);
    	})
    //Promise가 reject 된 경우의 동작을 정의
    	.catch(error => {
    	// catch 메소드 내부의 함수는 Promise가 reject 되었을 때 호출
    	// error을 인자로 받아 콘솔에 출력 
    		console.log(error); // error
    	});
    • new Error()를 사용하여 오류 객체를 생성하고, 이 오류 객체가 reject() 함수의 매개변수로 전달되어 Promise 객체가 실패 상태로 변경되었다.
      • Promise 객체에는 오류메시지를 설정할 수 있다.
      • 생성된 Error 객체를 통해 프로그램의 실행 흐름을 제어하고 오류를 처리할 수 있다.
      • .catch()를 통해 실패했을 시 오류 메시지를 설정하는 등 수행할 작업을 설정한다.
  • Promise 함수 예시
    function increaseAndPrint(n) {
    	return new Promise((resolve, reject) => {
    		setTimeout(() => {
    			const value = n + 1;
    			if (value === 5) { //value가 5일때 실패
    				const error = new Error();
    				error.name = 'ValueIsFiveError';
    				reject(error);
    				return;
    			}
    			console.log(value);
    			resolve(value);
    		}, 1000);
    	});
    }
    // 성공했을떄 실행
    increaseAndPrint(0).then((n) => {
    	console.log('result: ', n);
    })
  • 만약 then 내부에서 넣은 함수에서 또 Promise를 리턴하게 된다면, 이를 연달아서 사용할 수 있다.
    //1초 간격으로 1 2 3 4 출력하다가 
    //5가 출력할 당시 에러를 발생시켜 끝남
    increaseAndPrint(0)
    .then(n => {
    return increaseAndPrint(n);
    })
    .then(n => {
    return increaseAndPrint(n);
    })
    .then(n => {
    return increaseAndPrint(n);
    })
    .then(n => {
    return increaseAndPrint(n);
    })
    //value가 5가 되는 시점
    .then(n => {
    return increaseAndPrint(n);
    })
    // 에러 메시지 설정
    .catch(e => {
    console.error(e);
    });
    --------------------------------------------------------
    [ 간략하게 정리 ] 
    // .this()메소드에 increaseAndPrint함수 자체를 넘겨준거임
    increaseAndPrint(0)
    	.then(increaseAndPrint)
    	.then(increaseAndPrint)
    	.then(increaseAndPrint)
    	.then(increaseAndPrint)
    	.then(increaseAndPrint)
    	.catch(e => {
    		console.error(e);
    });
    • .then((value) ⇒ { incresaseAndPrint 함수 내용};

728x90

'JavaScript' 카테고리의 다른 글

Promise.all과 Promise.race  (0) 2024.04.21
async/await  (0) 2024.04.21
비동기식 처리 및 이벤트 루프  (1) 2024.04.21
클래스  (0) 2024.04.21
프로토타입  (0) 2024.04.21