본문 바로가기
Node.js

[Backend] 프로미스

by Hangii 2023. 1. 26.

콜백 헬이라고 불리는 지저분한 자바스크립트 코드의 해결책 = 프로미스

  • 프로미스: 내용이 실행은 되었지만 결과를 아직 반환하지 않은 객체. 결과가 출력되기 전까지 결과를 들고다닌다.
  • then이나 catch를 붙여서 결과를 반환받을 수 있다.
  • 실행이 완료되지 않았으면 완료된 후에 then 내부 함수가 실행됨

promise는 어떤 동작을 한다. 예를 들면 어떤 파일을 읽어 온다든지, 네이버와 같은 웹사이트에 요청을 보낸다든지. 동작의 결과(성공 or 실패)에 따라 실행되는 코드가 나뉜다.

  • resolve(성공 리턴값)를 호출하면 then으로 연결한다.
  • reject(실패 리턴값)를 호출하면 catch로 연결한다.
  • finally 부분은 무조건 실행된다.
const condition = true; //true면 resolve, false면 reject
const promise = new Promise((resolve, reject) => {
	if (condition) {
    	resolve('성공');
    } else {
    	reject('실패');
    }
});

promise
	.then((message) => {
    	console.log(message);  //성공(resolve)한 경우 실행
    })
    .catch((error) => {
    	console.error(error);  //실패(reject)한 경우 실행
    })

콜백은 코드 분리가 되지 않아 항상 실행할 코드를 바로 다음에 적어줘야한다.

setTimeout(() => {

}, 3000)

이런 식으로 setTimeout 함수를 쓸 때, 무조건 중괄호 {} 내부에 3초 후에 실행할 함수를 적어야 한다.

하지만 promise의 경우 실행을 먼저 해두고 나중에 필요할 때 then을 작성하는 부분에다가 실행하고자 하는 함수를 작성하면 된다. 코드 분리가 가능하다는 것이다.

const promise = setTimeoutPromise(3000);

console.log('딴짓');
console.log('딴짓');
console.log('딴짓');
console.log('딴짓');
console.log('딴짓');
console.log('딴짓');
console.log('딴짓');

promise.then(() => {
	console.log('지금 할래');
});
  • Promise.resolve(성공 리턴값): 바로 resolve하는 프로미스
  • Promise.reject(실패 리턴값): 바로 reject하는 프로미스
  • Promise.all(배열): 여러 개의 프로미스를 동시에 실행
    • 하나라도 실패하면 catch로 간다.
    • promise.allSettled로 실패한 것만 추려낼 수 있다.
const promise1 = Promise.resolve('성공1');
const promise2 = Promise.resolve('성공2');
Promise.all([promise1, promise2])
	.then((result) => {
    	console.log(result);  //['성공1', '성공2']
    })
    .catch((error) => {
    	console.error(error);
    });

async/await의 사용

  • promise를 사용해 긴 코드를 짜면 발생하는 콜백 헬을 피하기 위해 then 대신 await을 사용할 수 있다.
  • 변수 = await 프로미스; 인 경우, 프로미스가 resolve된 값이 변수에 저장된다.
  • 변수 await 값; 인 경우, 그 값이 변수에 저장된다.
async function findAndSaveUser(Users) {
	let user = await Users.findOne({});
    user.name = 'zero';
    user = await user.save();
    user = await Users.findOne({ gender: 'm' });
    //생략
}
  • async function도 프로미스이기 때문에 함수 내의 리턴값을 사용하려면 then을 사용해야한다.
  • async를 사용할 때 주의점은 반드시 try-catch문을 사용해야한다는 것이다. 이유는 async에는 resolve기능만 있고 reject기능이 없어서 함수 내에서 직접 처리해야하기 때문이다.
async function main() {
try{
    const result = await promise;
    return result;
} catch(error){
	console.error(error);
    }
}

//return 값을 받아와 사용하는 방법
1. main().then((name) => ...)  //result 값을 받아와 name에 저장
2. const name = await main()   //result 값을 받아와 name에 저장

 

'Node.js' 카테고리의 다른 글

[Backend] http 모듈로 서버 만들기  (0) 2023.01.30
[Backend] 노드 기능  (0) 2023.01.26
비구조화 할당  (0) 2023.01.26
화살표 함수  (0) 2023.01.25
템플릿 문자열, 객체 리터럴  (0) 2023.01.24

댓글