이롭게 현명하게

[JavaScript] 자바스크립트 동기와 비동기 / 동기와 비동기 원리 본문

웹 개발/JavaScript

[JavaScript] 자바스크립트 동기와 비동기 / 동기와 비동기 원리

dev_y.h 2023. 12. 7. 18:14
728x90
반응형

※ 본 포스팅은 패스트 캠퍼스 강의를 정리한 내용입니다.

 

 


 

목차

 

동기와 비동기

싱글 스레드 언어

자바스크립트 엔진이란?

비동기 실행과정

 


 

 

https://devyihyun.tistory.com/148

 


[동기와 비동기]

쿠팡의 과일 구매 목록이다.
웹페이지에 과일 목록이 보이기까지 1분이 걸린다고 하자
동기적으로 실행했다면 목록이 보이기까지 1분 동안 화면 스크롤, 버튼 클릭 등 아무것도 할 수 없다.
현재 실행하고 있는 함수가 있기 때문에 다른 일을 할 수 없어 다른 일들이 블록 된다.
즉, 브라우저에서 오래 걸리는 작업이 실행될 경우, 웹페이지의 UI는 멈춰버리고 사용자는 어떤 작업도 할 수 없다.

쿠팡 과일 목록

 

그렇기 때문에 비동기식으로 과일 목록을 불러와야 한다.
동기와 비동기, 동기는 하나씩 실행되고 비동기는 동시에 실행된다고 흔히들 알고 있다.
하지만 그렇지 않다. 비동기는 동시의 개념이 아니다. 자바스크립트는 싱글 스레드 언어이기 때문에 한 번의 실행으로 함수 2~3개가 실행되지 않는다.

 


[싱글 스레드 언어]

자바스크립트는 싱글 스레드 언어이다.

싱글 스레드언어는 한번에 하나의 작업만 할 수 있다.

건물을 짓는 인부가 한명이라고 생각하면 이해하기 쉽다. 이때 인부가 여러 명이 될 수는 없다.

인부 한 명이 한 번에 땅을 다듬고 철근을 세우고 시멘트 작업을 동시에 할 수 없다.

인부는 한 번에 하나의 동작밖에 할 수 없다.

인부가 많아지거나 인부의 팔이 늘어나 여러 가지 일을 동시에 할 수 없다.

자바스크립트도 마찬가지이다. 한 번에 하나의 작업만 가능하다. 동시에 실행할 수 없다.

함수가 실행되고 끝나야지 그다음 함수가 실행된다.

그래서 실행하고 있는 함수가 끝날 때까지 다른 함수들은 멈춰있다. 그러므로 비동기 실행이 불가능하다.

그러면 여기서 드는 의문점은 ‘ 어떻게 인부 한 명이 비동기로 실행되는가? ’이다.

 

한 번에 하나의 작업이 동기이다. 비동기는 동시가 아닌 순서의 문제이다.

동기와 다르게 비동기는 코드 순서랑 실제 순서가 다르다.

 

비동기 함수를 실행을 하면 동시에 실행이 되어야 하는데 자바스크립트는 싱글 스레드 언어라 그렇게 할 수 없다.
어떻게 할지 고민하다 결론은 비동기처럼 보이게 하자였다.
사실상 비동기는 눈속임이다.

 

 

자바스크립트는 위에서부터 아래로 코드를 훑고 내려오면서 실행어들을 실행한다.

자바스크립트 엔진에는 이벤트 루프(큐)라는 것이 있다.

실행어들이 스택으로 쌓이고 하나씩 실행되면서 사라진다.

비동기 함수이벤트루프(큐) 공간에 잠시 넣어두고 대기를 한다.

콜스택은 많은 역할 중에 호출된 함수가 콜스택에 push 되는 것을 말한다. 

콜스택 공간에 함수들이 모두 실행되고 비어졌을 때 이벤트 루프에 있는 비동기 함수가 콜스택 공간으로 옮겨지면서 실행이 된다.

자바스크립트는 싱글 스레드를 사용하기 때문에 콜스택에서 제거되기 전까지는 다른 어떤 함수도 실행되지 않는다.

이벤트 루프콜스택에 담기는 비동기를 큐에 넣었다가 스택이 비어있을 때 다시 넣어주는 역할을 한다.

 

 


[ 자바스크립트 엔진이란? ]

싱글 스레드에서 비동기가 처리된느 과정을 이해하려면 자바스크립트를 동작하는 엔진 구성 요소를 이해해야 한다.

자바스크립트 엔진은 자바스크립트 코드를 이해하고 실행을 도와준다.

자바스크립트 엔진은 메모리힙(Memory Heap)과 콜스택(call Stack)으로 구성되어 있다.

비동기와 관련된 구성요소는 WebAPIs, CallStack, Callback Queue, Event Loop 등이 있다.

자바스크립트 엔진 구조

 

자바스크립트 엔진만으로 웹이 동작하지는 않는다.

다른 외적인 요소들의 동작도 런타임으로 이루어진다.

브라우저에서 제공하는 WebAPI, 이벤트 등과 함게 동작하면서 런타임이 이루어진다.

버튼 클릭 이벤트, DOM 이벤트, HTTP요청, setTimeout 같은 비동기 함수는 WebAPI를 호출하며 WebAPI는 callback 함수를 callback Queue에 밀어 넣는다.

 

<자바스크립트 엔진>

  • Heap : 선언된 변수들이 메모리 할당이  일어나는 곳, 참조 데이터가 저장된다.
  • Call Stack : 코드 실행에 따라 호출 스택이 쌓이는 곳, 현재 어떤 함수가 동작하는지, 그 함수가 어떤 함수 내에서 동작하는지, 다음 호출되어야 할 함수는 어떤 함수인지 등을 기록

 

<비동기 처리>

Web APIs : 자바스크립트 엔진이 아니다. 브라우저에서 제공하는 API로 DOM,AJAX, setTimeout등이 있다. Call Stack에서 실행된 비동기 함수는 WebAPI를 호출하고, WebAPI는 콜백 함수를 callback queue에 넣는다.

Callback Queue (Micro Task Queue -> Task Queue) : 자바스크립트 런타임 환경에서 처리해야하는 명령어를 임시로 저장하는 대기큐로 비동기적으로 실행된 콜백함수가 보관된다.

  1. setTimeout에서 타이머 완료 후 실행되는콜백함수
  2. addEventListener에서 click 이벤트가 발생했을 때 실행되는 콜백 함수들을 보관
  3. Micro Task Queue : Task Queue보다 우선순위가 높다. Event Loop에서 Micro Task Queue에 쌓인 Task를 먼저 call stack에 넣은 뒤 Task Queue에 잔여 Task를 Call Stack에 올린다.
  4. 비동기적 작업이 완료되면 실행되는함수들이 대기하는 곳(Call Stack에 실행할 동작이 없을 경우)

Event Loop : Call stack과 Callback Queue의 상태를 확인하며 Call Stack이 빈 상태가 되면 Callback Queue의 첫번째 call back 함수를 Call Stack에 넣는다. 이러한 행위를 반복하여 Loop 라고 한다.

  1. 싱글 스레드인 자바스크립트의 작업을 멀티 스레드로 돌려 작업을 동시에 처리 똔느 여러 작업 중 우선순위를 적용해 동작 순서를 결정하는 컨트롤러 (브라우저 동작 타이밍 조절)
  2. 브라우저 내부의 Call Stack, Callback Queue, WebAPI등의 요소를 모니터링 하며 비동기 작업을 관리하고 이를 순서대로 실행시켜 프로그램의 실행 흐름을제어한다.(비동기 함수들을 적절한 시점에 실행)

Event Table : 특정 이벤트(timeout, click, mouse 등)가 발생한 경우 어떤 callback 함수가 호출되야 하는지 알고있는 자료 구조

 

 

<Web APIs의 종류>

Web API는 브라우저(크롬)에서 멀티 스레드로 구성되어 있어 비동기 작업에 대한 메인 스레드를 차단하지 않고 동시에 처리가 가능하다.

  • DOM : HTML문서의 구조와 내용을 표현, 조작할 수 있는 객체(동기적 처리)
  • XML HttpRequest : 서버와 비동기적으로 데이터를 교환할수 있는 객체(AJAX 기술의 핵심)
  • Timer API : 일정한 시간 간격으로 함수를 실행하거나 지연시키는 메소드 제공
  • Console API : 개발자 도구에서 콘솔 기능 제공 ( 동기적 처리)
  • Canvas API : <canvas>요소를 통해 그래픽, 애니메이션을 만들 수 있는 메소드 제공
  • Geolocation API : 웹 브라우저에서 사용자의 현재 위치 정보를 얻을 수 있는 메서드 제공

모든 Web API가 비동기적으로 동작하지는 않는다.

DOM API나 Console API는 동기적으로 처리, XML HttpRequest나 Timer API는 비동기적으로 처리한다.

 

<Callback Queue의 종류>

Task Queue와 Micro Task Queue 두 종류가 있다.

  • Task Queue : setTimeout, setInterval,fetch,addEventListener,console 과 같이 비동기로 처리되는 함수들의 콜백 함수가 들어있는 큐
  • Micro Task Queue : promise.then, Process.nestTick, MutationObserver와 같이 우선적으로 비동기로 처리되는 함수들의 콜백 함수가 들어가는 큐(처리 우선순위가 높다.)
    Micro가 먼저 처리되면 Tasck queue 차례로 처리

 

<Event Loop의 역할>

싱글 스레드인 자바스크립트의 작업을 멀티 스레드로 돌려 작업을 동시에 처리 또는 여러 작업 중 우선순위를 적용해 동작 순서를 결정하는 컨트롤러
브라우저 내부의 Call Stack, Callback Queue, Web API등의 요소를 모니터링하며 비동기 작업을 관리하고 이를 순서대로 실행시켜 프로그램의 실행 흐름을 제어하는 것이다.
브라우저의 동작 타이밍을 조절하는 관리자이다.

Event Loop의 역할

 

 


[비동기 실행 과정]

 Callback Queue는 Task Queue와 Micro Queue 두 종류가 있다.

다음 코드는 비동기가 실행되는 예시이다.

$.on('button', 'click', function onClick() {
    setTimeout(function timer() {
        console.log('You clicked the button!');    
    }, 2000);
});

console.log("Hi!");
function A(){
    B()
    console.log("func A")
}
A()
function B(){
    console.log("func B")
}

setTimeout(function timeout() {
    console.log("Click the button!");
}, 5000);

console.log("Welcome to loupe.");

 

 

자바스크립트 코드를 실행하면 $.on(‘button’… call stackpush 된다.




$.on(‘button’… pop 된 후 Web APIs로드된다.
이때 제이쿼리는 실행되지 않는다.
나중에 버튼을 클릭하게 된다면 Callback queue를 거쳐 이벤트 루프를 통해 Call Stackpush 된후 함수가 실행된다.




Console.log(“Hi!”) 를 읽은 후 call stackpush된다.





Call stack에서 pop 된 후 실행창에 출력된다.




Function A()를 호출하였다.




호출된 function A()call stackpush 된다.

 
 



Function A()에서 함수 B()를 호출한다.









호출된 function B()call stackpush 된다.





호출된 function B()에는 더 이상 호출할 함수가 없다.




호출된 function B()console.log(… callstackpush 된다.





Console.log(“func B”)pop 되어 결과 창에 나타난다.








호출된 B 함수의 실행이 모두 끝났기 때문에 B()pop 된다.





호출된 function A()console.log(… callstackpush 된다.






Console.log(“func A”)pop 되어 결과 창에 나타난다.





호출된 A함수의 실행이 모두 끝났기 때문에 A()pop 된다.






setTimeoutcallstackpush 된다.






setTimeoutcallstack에서 pop되어 Web APIs setTimeout으로 로드된다.






Timeout함수는 5000 5초 뒤에 실행되도록한다.






Console.logcallstackpush 된다.









Console.logcallstackpop 된 후 결과 창에 나타난다.









5초가 지난 뒤에는 callback queuepush 된다.







Call stack은 현재 비어있다.




이벤트 루프가 callback queue에 있는 함수들을 call stackpush 한다.






Timeout 함수 내용을 push 한다.












Call stack의 최상위 부분을 pop 한 결과를 출력한다.







Timeout 함수에서 더 이상 실행할 코드가 없어 call stack에서 pop 한다.







만약 버튼을 클릭했다면 callback queue push 한다.



Call stack비어있으므로 이벤트루프가 callback queue에있는 함수들을 call stackpush 한다.






onClick 함수 내용을 push 한다.









Call stack의 최상위를 pop 한 후 Web APIs에 로드 된다.
Timer 함수는 2초뒤에 실행된다.



2초가 지난 뒤 timer 함수는 callback queuepush 된다.



Call stack 비어있어 event loop가 실행되어 call stack push 된다.








Timer 함수 내용이 push 된다.







Call stack의 최상위를 pop 한 후 실행 결과를 출력한다.






함수에서 더 이상 실행할구문이 없어 call stack의 최상단을 pop 한다.









함수에서 더 이상 실행할구문이 없어 call stack의 최상단을 pop 한다.



 

이렇게 비동기 처리 과정이 끝이 난다.

이해가 잘 안됀다면 시뮬레이터를 사용해보는 것도 좋다.

<비동기 처리 시뮬레이>

 

http://latentflip.com/loupe/?code=JC5vbignYnV0dG9uJywgJ2NsaWNrJywgZnVuY3Rpb24gb25DbGljaygpIHsKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gdGltZXIoKSB7CiAgICAgICAgY29uc29sZS5sb2coJ1lvdSBjbGlja2VkIHRoZSBidXR0b24hJyk7ICAgIAogICAgfSwgMjAwMCk7Cn0pOwoKY29uc29sZS5sb2coIkhpISIpOwoKc2V0VGltZW91dChmdW5jdGlvbiB0aW1lb3V0KCkgewogICAgY29uc29sZS5sb2coIkNsaWNrIHRoZSBidXR0b24hIik7Cn0sIDUwMDApOwoKY29uc29sZS5sb2coIldlbGNvbWUgdG8gbG91cGUuIik7%21%21%21PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D

 

latentflip.com

 

 

 

 


잘못된 정보는 댓글에 남겨주시면 감사하겠습니다!😊

댓글과 좋아요는 큰 힘이 됩니다!

 

더보기

[ 참고자료 ]

 

https://ella951230.tistory.com/153

https://gist.github.com/jesstelford/9a35d20a2aa044df8bf241e00d7bc2d0

https://58cjdcns99.tistory.com/m/284

https://velog.io/@dishate/Javascript-%EC%BD%9C%EC%8A%A4%ED%83%9D%EA%B3%BC-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%A3%A8%ED%94%84-V8-%EC%97%94%EC%A7%84%EC%9D%98-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%B2%98%EB%A6%AC-%EB%B0%A9%EC%8B%9D

http://latentflip.com/loupe/?code=JC5vbignYnV0dG9uJywgJ2NsaWNrJywgZnVuY3Rpb24gb25DbGljaygpIHsKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gdGltZXIoKSB7CiAgICAgICAgY29uc29sZS5sb2coJ1lvdSBjbGlja2VkIHRoZSBidXR0b24hJyk7ICAgIAogICAgfSwgMjAwMCk7Cn0pOwoKY29uc29sZS5sb2coIkhpISIpOwoKc2V0VGltZW91dChmdW5jdGlvbiB0aW1lb3V0KCkgewogICAgY29uc29sZS5sb2coIkNsaWNrIHRoZSBidXR0b24hIik7Cn0sIDUwMDApOwoKY29uc29sZS5sb2coIldlbGNvbWUgdG8gbG91cGUuIik7!!!PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D

https://inpa.tistory.com/entry/%F0%9F%94%84-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%A3%A8%ED%94%84-%EA%B5%AC%EC%A1%B0-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC#settimeout_%EB%82%B4%EB%B6%80_%EB%8F%99%EC%9E%91_%EA%B3%BC%EC%A0%95

https://velog.io/@kirin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%97%94%EC%A7%84JavaScript-engine

 

 

<a href="https://www.flaticon.com/kr/free-icons/-" title="재 장전 아이콘">재 장전 아이콘  제작자: Radhe Icon - Flaticon</a>

https://www.google.com/url?sa=i&url=https%3A%2F%2Fnamu.wiki%2Fw%2FJavaScript&psig=AOvVaw1HcFLqJcnFCiLQvQV9FFHB&ust=1700198935350000&source=images&cd=vfe&opi=89978449&ved=0CA8QjRxqFwoTCPC6g9_kx4IDFQAAAAAdAAAAABAD

<a href="https://www.flaticon.com/kr/free-icons/" title="시계 아이콘">시계 아이콘  제작자: pictogramer - Flaticon</a>

 

728x90
반응형
Comments