JS | Core 와 ES6+ 한방에 때려잡기_비동기(5/5)

sik2·2021년 7월 17일
0

JavaScript

목록 보기
9/11

마지막 파트 입니다. 마지막 파트는 비동기적 처리에 쓰이는 키워드를 다룹니다.

콜백 헬과 같은 상황을 개선하기 위해 나온 ES6+ 키워드들 입니다.

마지막 파트에서는 비동기에 대한 개념과 promice, async, await에 대해 다룹니다.

개발자 남편이 장보는 방법.jpg

남편은 아마 이렇게 행동 했을 것입니다.

마트를 간다 ⇒ 우유를 산다 ⇒ 아보카드가 있는지 확인한다 ⇒ 아보카드가 있으므로 우유를 6개산다

이렇게 시키는 그대로 실행하는게 콤퓨타 프로세스 인데요. 단순 그자체...

비슷한 예로 라면 끓이는 프로세스를 생각해 봅시다.

  1. 물을 냄비에 넣는다 ⇒ 불을 켜고 타이머 3분을 맞춰 둔다 ⇒ 타이머가 끝나면 파를 송송 썬다 ⇒ 끓는 물에 면과 스프, 파를 넣는다 ⇒ 완성

이때 만약 이렇게 바꾸어 본다면?

  1. 물을 냄비에 넣는다 ⇒ 불을 켜고 타이머 3분을 맞춰 둔다 ⇒ 그사이 파를 송송 썬다 ⇒ 타이머가 끝나면 끓는 물에 면과 스프, 파를 넣는다 ⇒ 완성

1번과 다르게 2번에서는 끓는 시간 사이에 무언갈 할 수 있게 됩니다.

이런 처리를 비동기적 처리라고 합니다.

출처: 벨로퍼트와 함께하는 모던 자바스크립트

위 그림에서 1번이 끝나면 2번이 시작되고 2번이 끝나면 3번이 시작되는 구조 ⇒ 동기적

여러 작업을 동시에 처리할 수 있는 구조 ⇒ 비동기적

자바스크립트에서 setTimeout(), ajax 통신 등 다양한 경우에 비동기적 처리를 하고 있습니다.

call back hell

콜백 지옥은 비동기 처리 로직을 위해 콜백 함수를 연속해서 사용할 때 발생하는 문제입니다. 이런 가독성 떨어지는 코드를 보고 콜백 지옥이라고 합니다.

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

아도겐...

Promise

비동기적인 처리를 많이 하고 이를 중첩적으로 하다보면 코드가 굉장히 보기 불편해집니다.

이를 유지보수하기도 매우 힘들어지게되죠. 이러한 불편함 때문에 ES6+에서는 promice 키워드가 추가되었습니다.

Promise 는 new 키워드와 함께 사용 됩니다.

new Promise() 메서드를 호출할 때 콜백 함수를 선언할 수 있고, 콜백 함수의 인자는 resolve, reject입니다.
성공 ⇒ resolve 를 호출
실패 ⇒ reject 를 호출

new Promise(function(resolve, reject) {
  resolve();
});

resolve 를 호출 할 때 특정 값을 파라미터로 넣어주면, 이 값을 작업이 끝나고 나서 사용 할 수 있습니다. 작업이 끝나고 나서 또 다른 작업을 해야 할 때에는 Promise 뒤에 .then(...) 을 붙여서 사용하면 됩니다.

function getData() {
  return new Promise((resolve, reject) => {
    // ...
  });
}

// then() 으로 여러 개의 프로미스를 연결한 형식
getData()
  .then(function(data) {
    // ...
  })
  .then(function() {
    // ...
  })
  .then(function() {
    // ...
  });

예시 코드를 활용해 1초 마다 1씩 증가시킨 수 를 콘솔에 나타나게 할 수 있습니다.

function printPromise(n) {
	return new Promise((resolve, reject) => {
	  setTimeout(() => {
			const value = n + 1
			console.log(value);
	    resolve(value);
	  }, 1000);
	});
}
printPromise(0)
	.then(n => {
    return printPromise(n); // 1
  })
	.then(n => {
    return printPromise(n); // 2
  })
	.then(n => {
    return printPromise(n); // 3
  })

Promice를 통해 코드 기존의 콜백헬과 같은 문제를 해결되었습니다.
하지만

  1. then을 여러개 사용시 에러추적의 어려움

  2. 특정 조건의 분기의 어려움

    이 있었고 이를 해결하고자 ES8에 해당하는 문법으로 async/await이 추가됩니다.

async/await

async/await 문법
함수를 선언 할 때 함수의 앞부분에 async 키워드를 붙여 주어야 합니다.

await 을 넣어주면 해당 비동기처리 메서드(asyncFunc())를 기다렸다가 다음 작업을 수행 할 수 있습니다.

function asyncFunc() {
  return new Promise();
}

async function getData() {
  await asyncFunc();
}

아래 코드를 보자면 이전에 사용했던 초마다 value 값이 올라가는 printPromise() 함수를 선언했습니다.

이를 async await 키워드를 통해 비동기 처리 후 다음 작업을 처리할 수 있게 합니다.

process가 실행되며 '첫번째 출력'이 찍히며

await 키워드로 호출된 printPromise()의 '값은 : 1 두번째 출력' 이 1초 후 찍히며

다음으로 약간의 차이로 이어 '세번째 출력', '네번째 출력이 찍힙니다'

function printPromise(n) {
	return new Promise((resolve, reject) => {
	  setTimeout(() => {
			const value = n + 1
			console.log('값은 : '+value + ' 두번째 출력');
	    resolve(value);
	  }, 1000);
	});
}

async function process() {
  console.log('첫번째 출력');
  await printPromise(0); // 1초쉬고
  console.log('세번째 출력');
}

process()
	.then(() => {
	  console.log('네번째 출력');
	});

키워드의 사전적 의미 그대로 비동기(async) 처리가 될때 까지 대기(await) 했다가 다음작업을 수행할 수 있습니다.

+) 추가적으로 try catch 같은 예외처리 방법과 Promise.all Promise.race 도 알아보시면 좋습니다.

시리즈를 마무리하며

이 글은 2019년도에 작성한 글입니다. 노션에 기록해두었다가 사내 스터디 커뮤니티에 포스팅으로 올렸습니다. 잠깐 TMI로 글을 쓰게된 이유를 설명해보자면...

입사할때 Reactjs 포지션을 원해서 입사했지만 그때까지 줄 곧 관련 사업이 없어서 백엔드만 열심히 했었습니다. 그러다 기다리고 기다리던 React.js 구축 사업이 생겼었습니다.
그래서 다시 워밍업 차원에서 그때까지 공부했던 코어 자바스크립트와 es6문법을 같이 정리하기 위해 글을 썼던 걸로 기억합니다.

이 포스팅 외에도 v16.4에 추가된 Hooks 개념으로 간단한 앱도 만들고 열심히 했었는데 ... 결국 사업 참여가 외주사업 일정과 겹쳐서 힘들어지게 되었다는 헬피엔딩이었습니다😭😭😭
당시에 굉장히 좌절했던 기억이 남습니다. 허허허

현재는 이직을 해서 프론트엔드 팀에서 일을 하고 있습니다 🧑‍💻

글을 옮기면서 불필요한 내용을 덜어내는 등 글 일부를 수정하였습니다. 하지만 가독성을 위해 추가적으로 수정해야할 부분도 많이 보입니다. 이는 틈틈히 시간이 될때마다 수정할 예정입니다.(노션에서 긁어올때 들여쓰기 실화?...)

무튼 시리즈를 읽어주셔서 감사합니다 !

profile
기록

0개의 댓글