자바스크립트의 비동기 처리 - 1

Yunjjeong·2022년 12월 21일
0
post-thumbnail

이런저런 프로젝트에서 async/await, axios, fetch등을 사용해서 비동기 처리를 구현했지만, 정작 비동기 처리나 콜백함수에 대한 지식이 미흡하다는 생각이 들어 공부한 것을 기록하면서 포스팅 하기로 했습니닷 💪

비동기 처리란?

자바스크립트의 비동기 처리란 특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 자바스크립트의 특성을 의미합니다. 동시에 여러가지 작업을 처리할 수 있고 기다리는 과정에서 다른 함수를 호출할 수도 있습니다.

비동기 처리 사례 1 - ajax

ajax란 자바스크립트를 사용한 비동기 통신이며, 클라이언트와 서버간에 XML 데이터를 주고받는 기술입니다. 화면에 표시할 이미지나 데이터를 서버에서 불러와 표시해야 하는데, 이때 ajax 통신으로 해당 데이터를 서버로부터 가져올 수 있습니다.

function getData() {
	var tableData;
	$.get('https://domain.com/products/1', function(response) {
		tableData = response;
	});
	return tableData;
}

console.log(getData()); // undefined

위 코드는 https://domain.com 에다가 HTTP GET 요청을 날려 1번 상품(product) 정보를 요청하는 코드입니다. 여기서 $.get()이 ajax 통신을 하는 부분입니다.

요청 후 서버에서 받아온 데이터는 response인자에 담기고 tableData라는 변수에 저장됩니다. 하지만 맨 아래 getData()라는 함수를 호출한 결과는 undefined 입니다.

그 이유는 $.get()으로 데이터를 요청하고 받아올 때까지 기다려주지 않고 다음 코드인 return tableData; 를 실행했기 때문입니다.

이렇게 특정 로직의 실행이 끝날 때까지 기다려주지 않고 나머지 코드를 먼저 실행하는 것이 비동기 처리입니다.**

비동기 처리 사례 2 - setTimeout()

두번째 비동기 처리 사례는 setTimeout() 입니다. setTimeout()은 Web API의 한 종류로, 코드를 바로 실행하지 않고 지정한 시간만큼 기다렸다가 로직을 실행합니다.

// #1
console.log('Hello');
// #2
setTimeout(function() {
	console.log('Bye');
}, 3000);
// #3
console.log('Hello Again');

비동기 처리에 대한 생각 없이 코드를 읽다보면 다음과 같은 결과값을 예상하기 쉽습니다.

  • ‘Hello’ 출력
  • 3초 뒤 ‘Bye’ 출력
  • ‘Hello Again’ 출력

하지만 실제 결과값은 아래와 같습니다.

  • ‘Hello’ 출력
  • ‘Hello Again’ 출력
  • 3초 뒤 ‘Bye’ 출력

setTimeout() 이 비동기 방식으로 실행되기 때문에 일단 setTimeout()을 실행한 후 다음 코드인 console.log('Hello Again');으로 넘어갔습니다. 따라서, ‘Hello’, ‘Hello Again’를 먼저 출력하고 3초 뒤 ‘Bye’가 출력됩니다.

콜백 함수 - 비동기 처리의 문제점 해결하기

function getData(callbackFunc) {
	$.get('https://domain.com/products/1', function(response) {
		callbackFunc(response); 
 // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
	});
}

getData(function(tableData) {
	console.log(tableData); 
// $.get()의 response 값이 tableData에 전달됨
});

위 코드는 ajax 통신 코드를 콜백 함수로 개선한 코드입니다. 콜백 함수를 사용하면 특정 로직이 끝났을 때 원하는 동작을 실행시킬 수 있습니다.

콜백 지옥 & 해결 방안

콜백 지옥은 비동기 처리 로직을 위해 콜백 함수를 연속해서 사용할 때 발생하는 문제입니다.

$.get('url', function(response) {
	parseValue(response, function(id) {
		auth(id, function(result) {
			display(result, function(text) {
				console.log(text);
			});
		});
	});
});

웹 서비스를 개발하기 위해서는 서버에서 데이터를 받아와 표시하기까지 많은 과정이 필요합니다. 만약 모든 과정을 비동기로 처리해야 한다면 위와 같이 콜백 안에 콜백을 무는 형식으로 작성해야 합니다. 이런 방식은 가독성도 떨어지고 추후에 로직을 변경하기도 어렵습니다. 이러한 코드 구조를 콜백 지옥(callback hell)이라고 합니다.

코딩 패턴으로만 콜백 지옥을 해결하려면 아래와 같이 콜백 함수를 각각 분리해주면 됩니다.

function parseValueDone(id) {
	auth(id, authDone);
}
function authDone(result) {
	display(result, displayDone);
}
function displayDone(text) {
	console.log(text);
}
$.get('url', function(response) {
	parseValue(response, parseValueDone);
});

일반적으로는 코딩패턴을 사용하는 대신에 async/await이나 Promise를 사용하여 콜백 지옥을 해결합니다.

Promise나 Async에 대해서는 다음 포스팅에서 다뤄보도록 하겠습니다 !

profile
Studying FrontEnd Development

0개의 댓글