• 230213 TIL : 비동기 프로그래밍 (call stack, task queue, event loop)

    2023. 2. 14.

    by. 옛슬

    오늘은 비동기 프로그래밍에 대해서 공부했다.

    최근에 redux toolkit thunk를 공부하면서 약간 막혔는데

    그 이유가 내가 비동기 프로그래밍에 대해 얕게 알고 있어서가 아닐까?

    라는 생각이 들어서 기초부터 잡고 다시 공부해야겠다고 생각했기 때문이다 😂

     

    * 해당 공부자료는 유튜브 얄코 - 비동기 프로그래밍이 뭔가요? 글을 베이스로 다양한 인터넷 자료를 기반으로 만들어졌습니다 🍀


    비동기 프로그래밍

    동기 (Synchronous) vs 비동기 (Asynchronous)

    - 동기적 : 작성된 순서대로 실행됨 ↔ 비동기 : 코드가 순서대로 실행되지 않음.

     

    비동기는 왜 쓸까

    - 일반적으로 시간이 소요되는 작업에 사용됨 (네트워크 요청, 타임아웃 등)

    - 동기적으로 모든 코드를 사용하게 되면, 시간이 소요되는 작업이 있는 경우 그동안 아무것도 못하게 됨.

     

    자바스크립트가 비동기 작업이 가능한 이유는?

    - 가장 헷갈리는 부분은 바로 자바스크립트가 싱글 스레드라는 것이다.

    → 싱글 스레드 → 하나의 스레드 → 한번에 1 업무만 가능하다는 의미이다.

     

    근데 어떻게 비동기 작업이 가능할까

    - 브라우저에는 자바스크립트 엔진에서 제공하지 않는 여러가지의 기능이 존재한다.

    - 그 중 하나가 바로 Web API ( Web API는 DOM API, setTimeout, HTTP request 등을 포함한다)이다.

    - 이를 통해 비동기 작업이 가능하다.

     

    자바스크립트의 비동기 작업 로직

    function goToFriendHouse () {
    	console.log('집으로 이동 ~');
        
        setTimeout(function () {
        	console.log('손 씻기');
        }, 500);
        
        console.log('방 구경하기 ~');
    }
    
    function sayHello () {
    	console.log ('안녕!');
    }
    
    
    goToFriendHouse();
    sayHello();

    - 내가 만든 이상한 코드 🤣

     

    해당 코드를 간단하게 설명하면 

    - goToFriendHouse() 함수 호출

    - sayHello() 함수 호출

     

    1. goToFriendHouse() 코드 중 console.log('집으로 이동 ~') 출력

    2. goToFriendHouse() 코드 중 setTimeout()는 0.5초 후에 콜백함수를 출력하지만

        해당 코드의 콜백함수는 Web API로 이동된다 

    3. goToFriendHouse() 코드 중 console.log('방 구경하기 ~') 출력

    4. sayHello() 코드 중 console.log('안녕!') 출력

     

    - 이때 2번의 콜백함수는 0.5초 뒤에 바로 실행되는 것이 아닌 task queue에 들어가서 대기를 한다.

    - 이벤트 루프는 콜 스택에 빈 상태인지 확인 후 대기 상태인 큐를 순서대로 콜 스택에 push 한다. 즉, 2번의 콜백함수 내 코드는 콜 스택이 빈 이후 console.log ('손 씻기')가 출력 된다.

    - 이벤트 루프는 해당 큐와 콜스택을 연결해준다.

    자바스크립트의 Call Stack (호출 스택)

    - 자바스크립트는 하나의 콜 스택으로 이루어져있다. 그렇기 때문에 싱글 스레드이다.

    - 콜 스택은 데이터 구조 중 하나로 두가지의 일을 할 수 있다. add (push) 와 remove (pop)

    - 즉 어떤 함수가 실행될 때, 해당 함수는 콜스택에 push되며 리턴문을 만나거나 코드가 끝나면 pop된다.

     

    자바스크립트의 Task Queue (= Callback queue)

    - 데이터 구조 중 하나로 콜백 함수를 보유한다.

    - Web API가 제공

     

    🍊 간단 정리

    1. 자바스크립트는 하나의 콜 스택으로 이루어져 있어 싱글 스레드이기 때문에 한번에 1작업만 가능함.

    2. 하지만 브라우저는 Web API를 제공하며 Web API는 비동기 작업을 하도록 도와줌.

    3. Web API를 만나면 자바스크립트 엔진은 Web API에 요청한다.

       (콜 스택에 있던 Web API 함수는 Web API로 옮겨지는 것! → 그래서 해당 코드는 콜스택에 제거되고, 다음 작업을 실행할 수 있게 됨.)

    4. Web API는 해당 API를 처리 후, 콜백함수는 task queue에 담긴다.

    4. 이벤트 루프에서 콜 스택이 비었는지 확인 후 task queue에서 대기 상태인 콜백 함수를 push해주면 콜스택에서 차례대로 처리된다.

     

    여기서 핵심은 결론적으로 task queue에 대기 상태인 콜백 함수는 콜스택이 비었을 때만 처리될 수 있다는 점이다.


    분명히 비동기 프로그래밍 공부를 시작했는데

    끝은 자바스크립트의 코드가 작동하는 방식으로 끝났다 🤣

    하지만 해당 원리를 이해하지 못했다면 비동기 프로그래밍을 이해하지 못했을 수도?

    내일은 Promise 와 async/await를 공부해볼 예정이다 🥰

     

    * 그 외 참고자료

    https://slawinski.dev/blog/javascript-runtime-environment-web-api-task-queue-and-event-loop/

    https://felixgerschau.com/javascript-event-loop-call-stack/#callback-queue

    https://javascript.plainenglish.io/understanding-javascript-call-stack-task-queue-and-event-loop-2d586d5ad4db

    https://medium.com/jsninja/call-stack-event-loop-and-task-queue-d49eff2ec7bb

    https://dev.to/lydiahallie/javascript-visualized-event-loop-3dif

    댓글