본문 바로가기
TIL/코드스테이츠 TIL

코드스테이츠 소프트웨어 엔지니어링 부트캠프 68, 동기/비동기 이론복습

by 안뇽! 2021. 9. 24.
반응형

동기 / 비동기 이론 복습

 

여러가지 요청을 받는 자바스크립트는 싱글 쓰레드

자바스크립트는 차례대로 하나씩 실행하는 싱글 쓰레드이다. 하지만 웹 사이트에서는 여러가지 요청이 오갈 수 있다.

 

그렇다면 한번에 하나씩만 처리할 수 있는 자바스크립트는 어떻게 여러가지 요청을 처리할 수 있을까??

 

외부 홈페이지에서 날씨 정보를 다운로드 받아 화면에 표시하는 홈페이지가 있다고 생각해보자.

 

다운로드 받아야할 날씨 정보가 너무 많아 다운받는 시간이 오래걸리는 상황에서 동기적 코드는 날씨 정보가 다운로드 되는 동안 아무것도 하지 못한다.

 

하지만 비동기 코드는 <날씨 정보를 다운로드 받는 작업> 을 Task Queue(잠시 제껴두는 공간이라고 이해하자)로 잠시 제껴두고 다른 동기적 코드(로그인창 렌더링, 메뉴창 렌더링 등등)를 먼저 수행한다.

 

그 이후에 Task Queue에 잠시 제껴두었던 <날씨 정보를 다운로드 받는 작업> 을 Call Stack(작업판)으로 가져와 다운로드 받는다.

 

 

 

https://chanyeong.com/blog/post/44

  • Call Stack : 작업이 바로 실행되고 다 실행되면 작업이 빠진다.
  • Task Queue : 비동기 작업이 대기하고 있는 장소. Call Stack이 비어 있으면 Event Loop 의 명령에 따라 차례로 Call Stack에 들어간다.
  • Event Loop : 동기 / 비동기 작업의 순서를 관리한다.

 

 

비동기 처리

이렇게 자바스크립트는 필요에 따라 비동기 처리하여 각 작업이 처리되는 동안 렌더링이 일시중지 되는 현상을 방지한다.

비동기 처리는 보통 외부 자료에 접근하거나, 데이터 베이스에 접속하여 특정 데이터 가져오기 등의 기능에 주로 사용된다.

 

하지만 비동기 내부에서 순서를 정할 필요가 있다.

예를 들면, <데이터를 가져온다 -> 화면을 파란색으로 바꾼다> 기능을 비동기로 처리할때 순서가 없으면

<화면이 파란색으로 바뀐다-> 데이터를 다운받는다> 가 될 수 있기 때문이다.

 

비동기 처리의 3가지 방식

  1. 콜백
  2. Promise
  3. Async/Await

 

callback

 

콜백은 그냥 콜백을 이어붇는 것이다. 하지만 반복되면 Callback Hell이 나타난다. 이를 해결하기 위한 것이 Promise이다.

 

 

promise

 

callback 을 한덩어리로 묶어 callback hell을 해결하였다.

 

 

new Promise를 통해 인스턴스를 생성한다.

 

인자로는 콜백함수를 받는데 콜백함수의 인자로는 resolve, reject를 받는다.

 

비동기적으로 실행하는 작업의 결과를 객체로 나타낸 것인다. 그 결과의 상태에는 4가지가 있다.

 

  • pending : 아직 약속을 수행중, fulfilled나 rejected로 이어진다.
  • fulfilled : 약속이 지켜진 상태
  • rejected : 약속이 어떤 이유에서 못지켜진 상태
  • settled : 약속이 지켜졌든 안지켜졌든 결론이 난 상태

 

.then()이나 .catch()를 이용해 결과(fulfilled, rejected)에 따른 다음 작동을 실행한다.

 

 

var _promise = function (param) {
  return new Promise(function (resolve, reject) {
	// 비동기를 표현하기 위해 setTimeout 함수를 사용 
	window.setTimeout(function () {
		// 파라메터가 참이면, 
		if (param) {
			// 해결됨 
			resolve("해결 완료");
		}
		// 파라메터가 거짓이면, 
		else {
			// 실패 
			reject(Error("실패!!"));
		}
	}, 3000);
});
};

//Promise 실행
_promise(true)
.then(function (text) {
	// 성공시 .then()의 매개변수 text에 resolve의 인자인 '해결완료'가 할당된다.
	console.log(text);
})
.catch(error=>{console.log(error)})
//실패시 reject의 인자가 .catch()의 매개변수인 error에 할당된다.

 

하지만 이마저도 promise hell 이 존재한다. 이를 해결하기 위해 Async/await이 등장했다.

 

 

Async / Await

 

async는 promise를 반환한다. promise를 명시하지 않을 때에도 resolve로 값을 감싸 promise가 반환되도록 한다.

 

 

 

await은 비동기 처리 코드 앞에 붙힌다. 주의할 점은 비동기 처리 메서드가 꼭 promise를 반환해야 await가 의도한 대로 동작한다.

 

https://joshua1988.github.io/web-development/javascript/js-async-await/ 에 적혀있는 예문으로 설명을 하자면

 

 

function fetchItems() {
  return new Promise(function(resolve, reject) {
    var items = [1,2,3];
    resolve(items)
  });
}

console.log(fetchItems())//Promise {<fulfilled>: Array(3)} 
//[1,2,3]을 console.log하려면 뒤에 이어서 .then(console.log)를 붙혀주어야 함


async function logItems() {
  var resultItems = await fetchItems();
  console.log(resultItems); // [1,2,3]
}

console.log(logItems()) // [1,2,3]

 

async/await 는 편리함을 위한 syntactic sugar 일 뿐 promise에서 새로운것이 추가된 것은 아니다.

 

 

따라서 상황에 따라 적절하게 사용하면 된다.

반응형