dobyming

Promise 객체, async-await 함수를 활용한 비동기 처리

2023.01.26.

Promise 객체

동기: 콜백 지옥에서 탈출하기

비동기 작업이 가질 수 있는 3가지 상태

https://joshua1988.github.io/images/posts/web/javascript/promise.svg

  • Pending: 대기상태 (성공 or 실패)
  • Fulfilled: 성공 (Pending 상태에서 resolve 됐다)
  • Rejected: 실패 (Pending 상태에서 rejecet 됐다)

Promise 객체를 활용한 비동기 구문

// 기존 비동기 처리 
function isPositive(number,resolve,reject) {
	setTimeout(()=> {
		if(typeof number === 'number') {
			//resolve
			resolve(number >=0 ? "양수" : "음수");
		} else {
			reject("주어진 값이 숫자형이 아닙니다");
		},2000);
}

// Promise 객체를 반환하여 구현한 비동기 코드
function isPositiveP(number) {
	//실행자 
	return new Promise(resolve,reject) => {
		setTimeout(()=> {
			if(typeof number === 'number') {
				resolve(number >=0 ? "양수" : "음수");
			} else {
				reject("주어진 값이 숫자형이 아닙니다");
			},2000);
	};
}

const res = isPostiveP(101); //101

res
	.then((res) => { 
		console.log("작업 성공: ",res);
	}).catch((err)=>{
			console.log("작업에러")
	}); 

thencatch 구문을 활용하여 Fulfilled 상태인지 Rejected 상태인지 처리 결과값을 반환 받을 수 있습니다.

여러 개의 프로미스 연결하기 (Promise Chaining)

프로미스의 또 다른 특징은 여러 개의 프로미스를 연결하여 사용할 수 있다는 점입니다. 앞 예제에서 then() 메서드를 호출하고 나면 새로운 프로미스 객체가 반환됩니다.

function getData() {
  return new Promise({
    // ...
  });
}

// then() 으로 여러 개의 프로미스를 연결한 형식
getData()
  .then(function(data) {
    // ...
  })
  .then(function() {
    // ...
  })
  .then(function() {
    // ...
  });

async- await : 직관적인 비동기 처리 코드 작성

// async 예제
async function helloAsync() {
	return 'hello async';
} 

helloAsync() 함수 콘솔을 찍으면 Promise 객체를 반환하는데 이는 async 함수의 특징 중, Promise 객체를 반환하는 특징 때문입니다.

이때 다음 코드를 출력해보면 ‘hello async’가 정상적으로 콘솔에 출력됩니다. 이는 res 콜백함수가 helloAsync함수의 return을 바라봤다고 볼 수 있습니다.

helloAsync.then((res) => {
	console.log(res);
});
// await 예제
function delay(ms) {
	return new Promise(resolve) => {
		setTimeout((resolve,ms);
	});
}

async function helloAsync() {
	return delay(3000).then(()=> {
		return 'hello async';
	});
} 

위 함수를 async-await 구문으로 리팩토링하면 아래와 같습니다.

async function helloAsync() {
	await delay(3000);
	return 'hello async';
} 

async function main() {
	const res = await helloAsync();
	console.log(res);
} 
main(); // 3초 기다렸다가 'hello async' 반환

이때 await 함수는 동기적으로 수행되기 때문에, await에 선언된 구문을 먼저 수행을 해야 return할 수 있는 구조이다.

async-await 구문 정리

async function 함수명() {
  await 비동기_처리_메서드_명();
}

API 호출

API : 클라이언트와 서버간 통신할 수 있도록 도와줌 (request and response)

// <JSON placeholder를 활용한 API 호출 메소드 예제>
let response = fetch('Json Placeholder URL...').then((res) => 
	console.log(res)
);

이때 fetch() 함수에 hover시, Promise<Response> 로 Promise 객체를 반환함을 알 수 있습니다. 즉 fetch() 함수는 비동기 함수 임을 의미하고, then 키워드도 작성할 수 있습니다.

이를 이제 async-await 함수를 통해 리팩토링 시, 다음과 같습니다.

async functiong getData() {
	let rawResponse = await fetch('Json URL');
	let jsonResponse = await rawResponse.json();
	console.log(jsonResponse);
}
getData(); // 객체 배열 반환 
© 2024 Damin-Kim, Powered By Gatsby.