(미루던 일은 언젠가 끝마쳐야 하는 법)
js 공부할때부터 선입견으로 인해 미루고 있었던 비동기 처리에 대해 공부하고자 한다.
간단하게 동기, 비동기의 개념에 대해서 알고난 이후, 왜 이러한 처리 방법이 생겼는지 소개하겠다.
우선, 비동기 처리를 이해하기 위해서는 동기 처리가 무엇인지 알아야 한다.
동기(Synchronization): 어떤 일이 순차적으로 발생한다.
비동기(async): 어떤 일을 병렬적으로 실행한다.
자바스크립트의 특징 중 하나는 단일 스레드로 동작한다는 것이다.
(엥 단일 스레드요? 그게 뭐죠?)
쉽게 생각해서 단일 스레드란, 한번에 하나의 일을 처리하는 것. 이라 표현할 수 있다.
이러한 특징으로 인해 자바스크립트에서는 한가지 문제가 발생하게 된다.
너무 오래 걸리는 작업이 있으면 그 작업을 하느라, 다른 작업들은 그만큼 기다려야 한다는 점이였다. (블록킹)
이를 해결하기 위해 나온 개념이 비동기 처리이다.
특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 것을 비동기 처리라 부르고, 이를 이용해 코드의 블록킹을 방지한다.
서버의 API를 사용해야 하는 겅우, 네트워크 송수신 과정에서 시간이 걸리기 때문에, 비동기적으로 이러한 작업을 처리한다.
또한, 비동기 작업은 특정 작업을 예약할 때에도 사용한다.
아래는 자바스크립트에서 쓰이는 비동기적 처리 방식 기술들이다.
일정 시간이 지난 후에 함수를 실행
나중에 호출되는 함수
어떤 이벤트가 발생했거나 특정 시점에 도달했을 때 시스템에서 호출하는 함수이다.
function printName(){
console.log('자몽');
}
setTImeout(printName, 3000);
console.log('waiting..');
setTimeout을 통해 printName 함수는 3000(3초) 이후에 실행된다.
3초를 기다리는 동안 'waiting..'
은 먼저 실행되고, 이후 3초가 지나면 그제서야 printName 함수가 실행되어 '자몽'
이 출력된다.
콜백 함수로써 비동기를 처리하는 방법은 중첩으로 콜백 함수를 실행할 경우, 가독성이 떨어지게(콜백 지옥) 된다. 따라서 이를 해결하기위해 Promise가 생겼다.
비동기 처리를 도와주는 자바스크립트 내장 객체로, 다음과 같은 3가지 상태를 가진다.
.then
promise 가 종료가 되면 resolved 에 들어간 값을 받을 수 있다..catch
rejected 된 경우, catch 를 사용하여 에러를 잡아줄 수 있다.
`
참고(https://velog.io/@hayyim0626/TIL-Promise)
음.. 그래서 이해는 했는데 이걸로 어떻게 콜백 지옥을 해결하죠?
만약, 콜백 함수로 1초 뒤에 10을 더하는 함수를 작성하면 다음과 같이 콜백 지옥에 빠지게 된다.
increase(result, result=>{
console.log(result);
increase(result, result=>{
console.log(result);
(...)
하지만, Promise를 사용하면 다음과 같이 가독성이 매우 좋아지게 된다.
.then(number=>{
console.log(number);
return increase(number);
})
.then(number=>{
console.log(number);
return increase(number);
})
.catch(e=>{
console.log(e);
});
그렇다.. 이제는 (ES6도 구식이 되었나보다) ES8의 async/await를 알아보자.
async
를 붙이면 해당 함수는 항상 Promise를 반환한다.
await
키워드를 만나면 Promise가 처리(settled)될 때까지 대기한다. 결과는 그 이후 반환한다.
.catch
rejected 된 경우, catch 를 사용하여 에러를 잡아줄 수 있다.
사용법은 다음과 같다.
async function run(){
try{
let result = await increase(0);
console.log(result);
result = await increase(result);
console.log(result);
result = await increase(result);
console.log(result);
} catch(e){
console.log(e);
}
우와! 인기글! 우와! 멋있다! 우와 -!