마지막 파트 입니다. 마지막 파트는 비동기적 처리에 쓰이는 키워드를 다룹니다.
콜백 헬과 같은 상황을 개선하기 위해 나온 ES6+ 키워드들 입니다.
마지막 파트에서는 비동기에 대한 개념과 promice, async, await에 대해 다룹니다.
개발자 남편이 장보는 방법.jpg
남편은 아마 이렇게 행동 했을 것입니다.
마트를 간다 ⇒ 우유를 산다 ⇒ 아보카드가 있는지 확인한다 ⇒ 아보카드가 있으므로 우유를 6개산다
이렇게 시키는 그대로 실행하는게 콤퓨타 프로세스 인데요. 단순 그자체...
비슷한 예로 라면 끓이는 프로세스를 생각해 봅시다.
이때 만약 이렇게 바꾸어 본다면?
1번과 다르게 2번에서는 끓는 시간 사이에 무언갈 할 수 있게 됩니다.
이런 처리를 비동기적 처리라고 합니다.
출처: 벨로퍼트와 함께하는 모던 자바스크립트
위 그림에서 1번이 끝나면 2번이 시작되고 2번이 끝나면 3번이 시작되는 구조 ⇒ 동기적
여러 작업을 동시에 처리할 수 있는 구조 ⇒ 비동기적
자바스크립트에서 setTimeout(), ajax 통신 등 다양한 경우에 비동기적 처리를 하고 있습니다.
콜백 지옥은 비동기 처리 로직을 위해 콜백 함수를 연속해서 사용할 때 발생하는 문제입니다. 이런 가독성 떨어지는 코드를 보고 콜백 지옥이라고 합니다.
$.get('url', function (response) {
parseValue(response, function (id) {
auth(id, function (result) {
display(result, function (text) {
console.log(text);
});
});
});
});
아도겐...
비동기적인 처리를 많이 하고 이를 중첩적으로 하다보면 코드가 굉장히 보기 불편해집니다.
이를 유지보수하기도 매우 힘들어지게되죠. 이러한 불편함 때문에 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를 통해 코드 기존의 콜백헬과 같은 문제를 해결되었습니다.
하지만
then을 여러개 사용시 에러추적의 어려움
특정 조건의 분기의 어려움
이 있었고 이를 해결하고자 ES8에 해당하는 문법으로 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 개념으로 간단한 앱도 만들고 열심히 했었는데 ... 결국 사업 참여가 외주사업 일정과 겹쳐서 힘들어지게 되었다는 헬피엔딩이었습니다😭😭😭
당시에 굉장히 좌절했던 기억이 남습니다. 허허허
현재는 이직을 해서 프론트엔드 팀에서 일을 하고 있습니다 🧑💻
글을 옮기면서 불필요한 내용을 덜어내는 등 글 일부를 수정하였습니다. 하지만 가독성을 위해 추가적으로 수정해야할 부분도 많이 보입니다. 이는 틈틈히 시간이 될때마다 수정할 예정입니다.(노션에서 긁어올때 들여쓰기 실화?...)
무튼 시리즈를 읽어주셔서 감사합니다 !