[JS] 비동기

따봉도치 개발자·2023년 4월 19일
0

Javascript에서 비동기란?

Javascript는 Single Thread 언어이다.
즉, 싱글 스레드(Single Thread) 란 말 그대로 하나의 스레드만을 사용하여 여러 작업요청을 처리하는 방법이다. 하나의 콜스택 명령을 처리하는 node.js가 싱글 스레드의 대표적인 예라고 할 수 있다. 하지만, 여러 작업을 동시에 수행해야 하는 상황이 있다. 마우스(Click), 키보드 입력(Keydown), 페이지 로딩, 타이머API(setTimeout 등), fetch API, AJAX, 애니메이션 API 등이 있다.

Javascript 비동기 다루기?

Callback ?

비동기로 작동하는 코드를 제어할 수 있는 여러 방법중 하나인 Callback함수에 대해 알아보자. 콜백 함수는 다른 함수의 인자로써 이용되는 함수이고, 어떤 이벤트에 의해 호출되어지는 함수이다. 쉽게 말해 다른 함수가 실행이 끝난 뒤 실행되는 함수를 말한다.

function func(callback) {
	callback();
}
function callback() {
	console.log("callback이다");
}
func(callback) // "callback이다"

Promise ?

비동기 함수 호출 또는 연산이 끝났을 때, 성공과 실패를 처리하기 위한 함수를 설정하는 모듈이다. 비동기 처리를 가장 필요로 하는 XMLHTTPRequest 처리에서 유용하게 사용된다. 그럼 상황에 맞게 callback함수를 쓰면 되지 않냐는 생각을 할 수 있다! 하지만... 연속적인 비동기 처리를 할 때 (콜백 안에 콜백) x 100이 생긴다고 생각하면 가독성이 매우 떨어지고 로직도 변경하기 힘들어 지기 때문이다.

setTimeout(function() { // callback1
	console.log('A');
	setTimeout(function() { // callback2
		console.log('B');
			setTimeout(function() { // callback3
				console.log('C');
				setTimeout(function() { // callback4
					console.log('D');
				}, 5000);
			}, 5000);
	}, 5000);
}, 5000);

위와 같은 예시를 해결 하고자 Promiseasync/await을 사용한다.
이제 Promise의 대해 자세히 알아보자. Promise는 3가지 상태가 있다.
pending(대기): fulfilled(이행)도 rejected(거절)도 안된 초기 상태
fulfilled(이행): 비동기 연산이 성공적으로 완료된 상태, 결과값을 반환한다.
rejected(실패): 비동기 연산에 실패한 상태, 에러를 반환한다.
Promise는 class이기 때문에 new키워드를 통해 Promise객체를 생성하고 비동기 처리를 해줄 콜백 함수를 인수로 받는데 이 콜백 함수는 resolve, reject 함수를 인수로 전달받는다.

let promise = new Promise(function(resolve, reject) {
	resolve("성공");
});
promise
.then(value => {
	console.log(value);
	// "성공"
})
.catch(error => {
	console.log(error);
})
.finally(() => {
	console.log("성공이든 실패든 작동!");
	// "성공이든 실패든 작동!"
})

new Promise가 반환하는 Promise 객체는 state, result 내부 프로퍼티를 갖는다. 하지만 직접 접근할 수 없고 .then, .catch, .finally의 메서드를 사용해야 접근이 가능하다. 콜백 함수에 가 정상적으로 처리되면 resolve를 호출하고 .then 메서드로 접근 가능하다. 반대로, 콜백 함수에 에러가 생겼을 시 reject함수를 호출하고 .catch 메서드로 접근 할 수 있다. 마지막으로 콜백 함수가 정상 처리 여부와 관계없이 .finally메서드로 접근 가능하다.

Async/Await ?

async/await를 사용해 복잡한 Promise 코드를 간결하게 작성할 수 있다. 함수 앞에 async 예약어를 사용하고 비동기 처리할 함수await 키워드를 사용하면 된다. 이렇게 작성된 코드는 await 키워드가 작성된 코드가 동작하고 나서야 다음 순서의 코드가 동작하게 된다.

// 
const printString = (string) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve();
      console.log(string);
    }, Math.floor(Math.random() * 100) + 1);
  });
};
const printAll = async () => {
  await printString('A');
  await printString('B');
  await printString('C');
};
printAll();
console.log(
  `Async/Await을 통해 Promise를 간결한 코드로 작성할 수 있게 되었습니다.`
);
profile
Explain Like I'm 5

0개의 댓글