Little bIT awesome

비동기 처리 본문

자바스크립트

비동기 처리

까루카라 2023. 2. 17. 10:14

비동기 처리

특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 자바스크립트의 특성

자바스크립트의 비동기 처리 패턴

  1. callback : 특정 로직이 끝났을 때 원하는 동작을 실행시키기
  2. promise
  3. promise + generator
  4. async & await

비동기 처리의 사례 1

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

console.log(getData()); // undefined
  • $.get()로 데이터를 요청하고 받아올 때까지 기다려주지 않고 다음 코드인 return tableData; 를 실행했기 때문에 undefined. 따라서, getData()의 결과 값은 초기 값을 설정하지 않은 tableData의 값 undefined를 출력.

비동기 처리의 사례 2

// #1
console.log('Hello');
// #2
setTimeout(function() {
	console.log('Bye');
}, 3000);
// #3
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에 전달됨
}); 
  • 이렇게 콜백 함수를 사용하면 특정 로직이 끝났을 때 원하는 동작을 실행할 수 있다.

콜백 지옥

$.get('url', function(response) {
	parseValue(response, function(id) {
		auth(id, function(result) {
			display(result, function(text) {
				console.log(text);
			});
		});
	});
});
  • 비동기 처리 로직을 위해 콜백 함수를 연속해서 사용할 때 발생하는 문제.
  • 가독성도 떨어지고, 로직을 변경하기도 어렵다.

콜백 지옥을 해결하는 방법

1. 코딩 패턴으로만 해결

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);
});

2. Promise, Async

Promise

  • 자바스크립트 비동기 처리에 사용되는 객체
  • 주로 서버에서 받아온 데이터를 화면에 표시할 때 사용
function getData(callbackFunc) {
  $.get('url 주소/products/1', function(response) {
    callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
  });
}

getData(function(tableData) {
  console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});
  • 콜백함수로 비동기 처리
function getData(callback) {
  // new Promise() 추가
  return new Promise(function(resolve, reject) {
    $.get('url 주소/products/1', function(response) {
      // 데이터를 받으면 resolve() 호출
      resolve(response);
    });
  });
}

// getData()의 실행이 끝나면 호출되는 then()
getData().then(function(tableData) {
  // resolve()의 결과 값이 여기로 전달됨
  console.log(tableData); // $.get()의 reponse 값이 tableData에 전달됨
});
  • Promise를 사용하여 비동기 처리

프로미스의 3가지 상태(states)

  1. Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
  2. Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
  3. Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태

Pending(대기)

new Promise(function(resolve, reject) {
	// ...
});
  • Promise 메서드 호출, 콜백함수 선언
  • 콜백함수의 인자는 resolve와 reject

Fulfilled(이행)

new Promise(function(resolve, reject) {
	resolve();
});
  • 콜백함수의 인자 resolve를 아래와 같이 실행
function getData() {
	return new Promise(resolve, reject) {
		var data = 100;
		resolve(data);
	});
}

// resolve()의 결과 값 data를 resolvedData로 받음
getData().then(function(resolvedData) {
	console.log(resolvedData);
});
  • 그리고 이행 상태가 되면 then()을 이용하여 처리 결과 값을 받을 수 있다.

Rejected(실패)

  • 프로미스 객체를 생성하면 콜백 함수 인자로 resolve와 reject를 사용할 수 있는데 이때, reject를 호출하면 실패 상태가 된다.
new Promise(function(resolve, reject) {
	reject();
});
  • 실패 상태가 되면 실패한 이유(실패 처리의 결과 값)를 catch()로 받을 수 있다.
function getData() {
  return new Promise(function(resolve, reject) {
    reject(new Error("Request is failed"));
  });
}

// reject()의 결과 값 Error를 err에 받음
getData().then().catch(function(err) {
  console.log(err); // Error: Request is failed
});