본문 바로가기
취준적인

Promise를 사용한 비동기 통신, Async · Await 비동기 통신의 차이점

by klm hyeon woo 2023. 2. 12.

Promise와 Async · Await의 차이점

에러 핸들링 측면

Promise를 활용할 시에는 .catch() 문을 통해 에러 핸들링이 가능하다.

Async · Await은 에러 핸들링 할 수 있는 기능이 없어 try-catch() 문을 활용해야한다.

 

코드 가독성

Promise의 .then() 지옥 가능성 (아래 내용에서 예시로 확인이 가능하다)

코드가 길어지면 길어질수록, Async · Await 을 활용한 코드가 가독성이 좋다.

Async · Await 은 비동기 코드가 동기 코드처럼 읽히도록 가독성이 좋고, 흐름을 이해하기 쉽게 해준다.


자바스크립트에서 비동기 처리는 왜 필요할까?

자바스크립트는 동기적인 언어이다. 즉, 코드 하나하나가 처리되면서 지연시간이 발생하면 이후의 태스크들은 무아지경으로 블로킹이 되어진다. 서버에 데이터를 요청하는 등, 대기 시간이 긴 작업의 경우에는 무아지경의 지연시간을 해소하기 위해 병렬적인 함수 실행을 해야하는데, 이때 나오는 개념이 비동기처리이다.

function printData() {
	const data = getData();
    console.log(data);
}

위의 코드를 보자, getData() 함수가 서버에서 데이터를 가져오는 함수라고 할때 서버에서 데이터를 즉각적으로 받아오는 것이 아닌, 서버에서 데이터를 받아올 때는 일정 대기시간이 소요된 후에 데이터를 받아오게 된다.

 

printData() 함수를 실행하게 되면, data의 값은 아무것도 지정되어있지 않은 undefined라는 값이 들어오게된다.

자바스크립트는 기본적으로 동기적인 언어의 특성을 가지고 있지만, 서버에서 데이터를 가져오는 작업의 경우는 비동기로 작업을 해야한다.

 

비동기 처리 방식에는 Promise와 Async · Await 방식을 사용한다.

서버에서 데이터를 가져오는 경우, 응답 값을 받기 위해 보통 자바스크립트에서 비동기 처리 방식인 Promise, Async · Await 방식을 사용한다. 두 방식의 용도는 같지만 분명 다른 점이 존재한다.

 

Async · Await 방식은 Promise에 비해 가독성이 좋고, 문법이 간결하다.

function getText() {
	return newData((resolve, reject) => {
    	$.get("API 주소", function((res) => {
        	if (res) {
            	resolve("데이터를 성공적으로 불러왔습니다");
            }
        });
        reject("데이터를 불러오는데 실패했습니다");
    });
}

function printText() {
	getText().then((data) => {
    	console.log(data):
    });
}

Promise의 일반적인 then 처리 방법이라면 위와 같이 코드를 작성하게 된다.

하지만, async의 경우 async 함수에 await을 붙여주기만 하면, 함수 처리가 끝날 때까지 기다려달라는 의미로 생각을 할 수 가 있다.

function getText() {
	return newData((resolve, reject) => {
    	$.get("API 주소", function((res) => {
        	if (res) {
            	resolve("데이터를 성공적으로 불러왔습니다");
            }
        });
        reject("데이터를 불러오는데 실패했습니다");
    });
}

async function printText() {
	const text = await getText();
    console.log(text);
}

위와 같이 Promise와 Async · Await 문법의 차이점을 볼 수 있는데, 위와 같이 코드의 길이가 짧은 경우 간결성 측면에서 큰 차이가 나지 않는 것을 볼 수가 있다. 하지만 데이터를 요청하여 처리까지 한다면 간결성의 차이를 명확하게 알 수가 있다.

function getText() {
	return newData((resolve, reject) => {
    	$.get("API 주소", function((res) => {
        	if (res) {
            	resolve({name : "홍길동", property : "홍길동의 특성"});
            }
        });
        reject("데이터를 불러오는데 실패했습니다");
    });
}

function printText_Promise() {
	return getText()
    .then((data) => {
    	if (data.property) {
        	return sampleFunc1(data)
            .then(anotherData => {
            	console.log(anotherData);
            }
        } else {
        	console.log(data);
        }
    }
}

async function printText_Async() {
	const text = await getText();
    if (text.property) {
    	const sampleData = await sampleFunc1(text);
        console.log(sampleData);
    } else {
    	console.log(text);
    }
}

함수 안에서 추가적인 데이터 처리 방식을 첨가해보았다. Promise는 .then을 통해 많은 들여쓰기를 하고, 다소 복잡한 양상을 띄고 있다. 하지만 Async · Await과 같은 경우, 응답 값을 명시적인 변수에 담아 사용하므로 직관적인 변수를 인식할 수 있으며, 간결하다는 장점을 가지고 있다.

 

Async · Await 방식은 에러 핸들링에 유용하다.

 

서버에 데이터를 요청하는 작업을 하다보면, 에러가 발생하기 나름인데 이 때문에 우리는 에러 핸들링 해줘야한다.

function getText() {
	return newData((resolve, reject) => {
    	$.get("API 주소", function((res) => {
        	if (res) {
            	resolve({name: "홍길동", property : "홍길동 특성"});
            }
        });
        reject("데이터를 불러오는데 실패했습니다");
    });
}

function printText_Promise() {
	try {
        getText().then((data) => {
            const person = JSON.parse(data); // JSON.parse 과정에서 에러가 발생!
            console.log(person);
        });
        .catch((err) => {
            console.log(err);
        });
        }
    catch(err) {
    	console.log(err);
    }
}

function printText_Async() {
	try {
    	const data = await JSON.parse(getText());
        console.log(data);
    }
    catch(err) {
    	console.log(err);
    }
}

위의 코드에서 try 문에 들어가있는 .catch 코드, try 문의 .catch 코드가 보일 것이다. 코드가 직관적이지 않으며 동시에 에러를 처리하는 catch 문의 중복성이 눈에 띄고 있다. 

function sample_Promise() {
	return sampleFunc() 
    	.then(data => return data)
        .then(data2 => return data2)
        .then(data3 = > return data3)
        .catch(err => console.log(err)) // 결과적으로 문제가 발생했으나, 어디가 문제인지 모름
};

function sample_Async() {
	const data1 = await sampleFunc(); // 문제가 발생하게 되면, data1 값이 유효하지 않음!
    const data2 = await data1;
    console.log(data2);
}

하지만 Async · Await을 사용하게 되면 하나의 catch문만 사용을 하면 되고, 해당 catch문에서 try 내부에서 발생하는 모든 에러에 접근이 가능하다. 이처럼 Promise의 then, Aysnc · Await은 용도가 같지만 간결성, 에러 핸들링, 에러 위치 확인 측면에서 차이가 있음 알 수 있다. 이외에도 Async · Await은 디버그를 할 때 then과 달리 정확한 위치를 지정할 수 있는 장점이 있다.


레퍼런스

 

Promise와 async/await 차이점

자바스크립트에서 비동기 로직 처리를 다룰때 자주 사용되는 Promise, async/await에 대해 알아보자

velog.io

 

 

promise와 async await의 차이점

이번 포스팅에서는 promise, async await의 차이점에 대해 알아보았다. 혹시 promise, async await을 모른다면 이 포스팅을 참고해보자! 1. js에서 비동기 처리는 왜 필요할까? js는 동기적인 언어이지만, 서

mong-blog.tistory.com

 

댓글