-
[Javascript] 콜백 함수와 비동기 처리 part 1Development/Javascript 2020. 8. 14. 02:40728x90
🖐 들어가기 전에
비동기가 도대체 뭔데?!!!!
무턱대고 자바스크립트 코드를 작성 할때 항상 의문이였던건 비동기라는 것이였다.
asyn/await만 붙이면 모든 함수들이 비동기가 되는줄 알아서 모든 함수에 asyn 붙이고...🤦♀️
개념이 확실히 안 잡힌 상태에서 무작성 코드를 작성하니 갈수록 혼란해지고 답답한 마음이 커졌다.
이번 포스팅을 통해서 자바스크립트의 콜백 함수와 비동기 처리에 대해 확실히 이해하는 것이 목표다!
💁♀️ 사전에 알아야될 용어 정리
1. 동기
동기란 요청이 들어온 순서에 맞게 하나씩 처리하는 방식으로,
요청 들어온 작업이 끝날 때 까지 기다렸다가 응답을 즉시 처리하고 다음으로 넘어간다.
2. 비동기
비동기란 하나의 요청에 따른 응답을 즉시 처리하지 않아도, 그 대기 시간동안 또 다른 요청에 대해 처리 가능한 방식이다.
요청 들어온 작업을 수행하는 대기시간 동안 다른 요청을 처리하다가 요청이 완료됬다는 이벤트 핸들러(callback 함수)의 알림이 오면 처리한다.
3. 블로킹
블로킹은 자신의 수행결과가 끝날 때까지 제어권을 갖고 있는 것을 의미한다.
4. 논블로킹
논블로킹은 자신이 호출되었을 때 제어권을 바로 자신을 호출한 쪽으로 넘기며, 자신을 호출한 쪽에서 다른 일을 할 수 있도록 하는 것을 의미한다.
🏃♀️ 자바스크립트의 동작원리
자바스크립트는 싱글 스레드 기반의 언어다.
싱글 스레드란 '한번에 하나의 작업만을 수행한다.'라는 개념이다.
자바스크립트의 특징을 보면 비동기, 동시성, 논블로킹(Non Blocking) I/O 등이 있다.
그럼 한번에 하나의 작업만을 수행하면서 어떻게 동시성을 갖을 수 있을까?
그건 바로 자바스크립트가 비동기적으로 동작하기 때문에 싱글 스레드 기반이지만 동시에 많은 작업을 수행할 수 있기때문이다.
여기서 중요한 점은 비동기로 동작하는 핵심요소는 자바스크립트 언어가 아니라 자바스크립트 런타임이다.
런타임이란 프로그래밍 언어가 구동되는 환경으로 브라우저 또는 nodeJS를 말한다.
위의 이미지가 바로 자바스크립트 코드가 실행되면서 자바스크립트 런타임과 동작하는 요소들이다.
구성요소를 살펴보면, 아래와 같다.
-
메모리 힙: 메모리 할당을 담당하는 곳.
-
콜 스택: 코드가 호출되면서, 실행 컨텍스트가 쌓이는 곳.
-
Web APIs: DOM, AJAX, setTimeout 등 브라우저 자체에서 제공하는 API.
-
이벤트 루프: 이벤트 발생 시 호출되는 콜백 함수들을 관리하여 콜백 큐에 전달하고, 콜백 큐에 담겨있는 콜백 함수들을 콜 스택에 넘겨준다.
-
콜백 큐: web api에서 비동기 작업들이 실행된 후 호출되는 콜백함수들이 기다리는 공간으로 이벤트 루프가 정해준 순서대로 줄을 서있으며, FIFO(First In First Out) 방식.
console.log('one'); setTimeout(sample, 1000); function sample() { console.log('two'); }; console.log('three');
필자가 위와 같은 코드를 작성했을 때, 구성요소들은 어떤 동작을 하는지 알아보겠다.
가장 먼저 console.log('one')이 콜 스택에 쌓이고, 바로 실행되어 콜 스택에서 제거된다.
그 다음 setTimeout이 콜 스택에 쌓이고, 실행되면 Browser API인 timer를 호출하고, 콜 스택에서 제거된다.
그 다음 console.log('three')가 콜 스택에 쌓이고, 바로 실행되어 콜 스택에서 제거된다.
setTimeout 시간이 지나면 콜백 큐에 콜백 함수가 추가된다.
그럼 이벤트 루프가 콜 스택이 비어있는것을 확인하고 콜 스택에 콜백 함수를 추가해서 실행한다.
※ 이벤트 루프는 콜 스택이 비어있을 경우, 콜 스택 큐에서 함수를 꺼내서 콜 스택에 추가한다.
따라서, 결과는 아래과 같이 출력된다.
one three two
결국, 이런 동작 때문에 자바스크립트는 비동기적으로 동작할 수 있다.
😈 콜백지옥과 비동기 제어
setTimeout(function () { console.log("one"); setTimeout(function () { console.log("two"); setTimeout(function () { console.log("three"); setTimeout(function () { console.log("four"); }, 1000); }, 1000); }, 1000); }, 1000);
필자는 위와 같이 1초 간격으로 콘솔 로그를 찍는 코드를 작성했다.
이런식으로 계속 해서 콘솔 로그를 추가한다면 당신은 지금 콜백지옥에 빠진 것이다.
하지만, 이런 문제점을 해결하고자 자바스크립트는 웹의 복잡도가 증가한 만큼 비동기적인 코드를 동기적으로 처리해주는 장치를 마련하기위해 끊임없이 노력해왔고 그 결과, ES6에서 Promise, Generator 등이 도입됐고, ES2017에서 async/await가 도입됐다.
여러 방법으로 비동기를 처리하는 포스팅은 다음 포스팅에 이어서 하는걸로..🥳
참고 자료
- Javascript 동작원리 (Single thread, Event loop, Asynchronous)
- JavaScript 비동기 핵심 Event Loop 정리
- 동기(synchronous)와 비동기(asynchronous) / 블로킹(blocking)과 논블로킹(non-blocking)
🎉 피드백은 언제나 환영입니다. 🎉
728x90'Development > Javascript' 카테고리의 다른 글
[Javascript] 배열 메서드 정리 (0) 2020.12.26 [Javascript] Prettier과 ESLint로 코드 예쁘게 유지하기 (0) 2020.10.10 [Javascript] 실행 컨텍스트(execution context) (0) 2020.08.27 [Javascript] 콜백함수와 비동기 처리 part 2 (0) 2020.08.18 [Javascript] 불변객체? 불변성? 그게 뭐에요?!! (0) 2020.08.13 -