Promise & async/await

김맥스·2023년 3월 11일
0

자바스크립트

목록 보기
2/5
post-thumbnail

Promise & async/await

1. Promise

찾아보게 된 계기

async sendMessage(email, otp) {
    await axios({
      method: "post",
      url: this.MAILGURN_URL + `v3/${process.env.MAILGUN_DOMAIN_NAME}/messages`,
      auth: {
        username: "api",
        password: process.env.MAILGUN_API_KEY,
      },
      params: {
        from: "Excited User <me@samples.mailgun.org>",
        to: email,
        subject: `otp`,
        text: `Your PixelSC verification code is ${otp}`,
      },
    }).then(
      (response) => {},
      (reject) => {
        console.log(reject);
      },
    );
  }

Promise 란?

const condition = true; // true면 resolve, false면 reject

const promise = new Promise((resolve, reject) => {
	if (condition) {
		resolve('성공');
	} else {
		reject('실패');
	}
// 이 부분은 동기로 실행되어서 promise 변수에서 들고 있다가 원할때 꺼내 쓴다 ✅
});

// 중간에 다른 코드가 들어갈 수 있음

promise // 이렇게 .then을 붙이면 결과를 반환함
	.then((message) => { // 성공(resolve)한 경우 실행
		console.log(message);
	})
	.catch((error) => { // 실패(reject)한 경우 실행
		console.error(error);
	})
	.finally(() => { // 끝나고 무조건 실행
		console.log('무조건 실행')
	})
  • 내용이 실행은 되었지만 아직 결과를 반환하지 않은 객체
  • 프로미스 객체를 만들고 실행해야 한다.
  • 실행이 완료되지 않았으면 완료된 후에 then 내부 함수가 실행된다

✅ promise와 callback 함수의 차이점

  • callback : 3초뒤에 실행되어야 함수를 따로 분리할 수 없다. 3초 뒤에 바로 실행됨
    setTimeout(() => {}, 3000)
  • promise : 코드를 분리할 수 있음 → 원하는 때에 사용 가능
    // setTimout 프로미스가 있다고 가정해보면
    
    const promise = setTimeoutPromise(3000)
    
    console.log('딴짓')
    console.log('딴짓')
    console.log('딴짓')
    console.log('딴짓')
    console.log('딴짓')
    
    promise.then(() => {
    	right now
    });
  • node 생태계가 거의 다 callback 에서 promise로 전환이 되고 있는 추세이기 때문에 promise를 아는게 좋다

Promise.all(배열)

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);
	});
  • 여러 개의 프로미스를 동시에 실행
  • 하나라도 실패하면 catch로 감
  • 요즘에는 all도 잘 안쓰고 allSettled를 쓰는데, 이걸로 실패한 것만 추려낼 수 있음

2. async/await

기존 promsie 패턴 코드

function findAndSaveUser(Users) {
	Users.findOne({})
		.then((user) => {
			user.name = 'max';
			return user.save()
		})
		.then((user) => {
			return Users.findOne({ gender: 'm' });
		})
		.then((user) => {
			// 생략
		})
		.catch(err => { 
			console.error(err);
		});
}

async/await 으로 변환

async function findAndSaveUser(Users) {
	let user = await User.findOne({});
						 // 먼저 실행되어서 user 변수에 저장
	user.name = 'max'
	user = await user.save();
	user = await Users.findOne({ gender: 'm' });
	// 생략
}
  • 변수 = await 프로미스; 인 경우 프로미스가 resolve된 값이 변수에 저장
  • 변수 await 값; 인 경우 그 값이 변수에 저장
  • async 함수는 항상 promise를 반환한다
  • async는 promise의 성질을 그대로 갖는다고 보면 된다. 그래서,
    async function test() {
    	const result = await promise;
    	return result
    }
    
    // 라고 하면
    
    test().then((name) => ... )
    // 1. then으로 받던지
    
    const name = await test()
    // 2. await으로 받아야 한다
  • 다만 await은 promise가 실패하면 받아주는 catch가 없기 때문에 try … catch 구문으로 감싸줘야 한다.

for await ( 변수 of 프로미스 배열 )

  • resolve된 프로미스가 변수에 담겨 나옴
  • await을 사용하기 때문에 async 함수 안에서 해야 함
profile
3년차 백엔드 개발자의 공부 기록

0개의 댓글