[그린컴퓨터] 클라이언트/Javascript

동기(Sync)와 비동기(Async) { 일반함수와 콜스택메모리, 비동기함수(setTimeout) 처리과정 }

Ben의 프로그램 2023. 6. 30. 13:04
728x90

  • 동기적 처리란 예를 들면 이런 것이다. 

    카운터에 직원이 있다면 카운터는 손님 한명 한명 씩 기다린 순서대로 처리한다. 
    즉, 하나의 작업이 시작되고 난 이후에 완료되면 그 다음 작업이 진행되는 것을 동기적 처리라고 얘기한다. 

    실제 웹에서 예를 들어보자면 아이디 중복체크가 있다. 아이디 중복 체크 버튼을 클릭하는 순간 사용자는 다른 활동을 할 수가 없다. 이는 개발자들이 의도한 바인데, 아이디 중복은 중요한 문제이기 때문에 사용자가 다른 작업을 하지 못하도록 만든 것이다. 동기식으로 처리하면 이처럼 사용자가 다른 작업을 할 수 없게 됩니다. 
  • 비동기적 처리란 예를 들면 이런 것이다.

    카운터에 직원이 있다면 카운터 직원은 손님이 올 때마다 바로 작업을 시작한다. 즉 여러 명이 오면 오자 마자 각자의 작업을 처리해주기 시작한다. 동기적 처리와 다르게 이전 작업이 끝날 때 까지 기다리지 않고 다음 작업을 시작할 수 있게 된다. 

    실제 웹에서 예를 들어보자면 만약 아이디 중복 체크를 비동기식으로 처리했다면 사용자는 중복 체크 버튼을 눌러놓고 비밀번호와 다른 작업들을 할 수 있게 된다. 

  • 자바스크립트는 함수를 동기식으로 처리하는데, 비동기식 처리를 하는 함수도 있다.

    즉, 자바스크립트는 동기식 & 비동기식 처리가 모두 가능합니다. 

    일반 함수는 동기식으로 처리되는데, 그림과 함께 이해해 보겠습니다. 

    일반 함수는 함수가 호출되면 스택에 차곡 차곡 쌓이게 됩니다. 

    비동기 함수는 대기실 background 에 가서 대기하다가 응답이 오면 스택으로 와서 실행됩니다. 

  • 일반 함수 먼저 살펴보겠습니다. 

function first() {
    second();
    console.log('첫번째');
}

function second() {
    third();
    console.log('두번째');
}

function third() {
    console.log('세번째');
}

first();
 
  • 일반 함수는 동기식으로 처리 됩니다. first( ) 함수가 실행되면 first - second - third 순서로 함수가 호출되고 이것이 의미하는 것은 스택 메모리에 first - second - third 순서로 쌓여있다는 것이고, 스택 메모리는 FILO 이기 때문에 마지막에 스택 메모리에 들어온 것이 먼저 실행 됩니다. 
 


console.log('=== 시작 ===');

setTimeout(function callback() {
    console.log('=== timer 종료 ===')
}, 3000);
// 3 초를 기다렸다가 문자를 출력하는 코드이다.

console.log('=== 종료 ===');
 
  • setTimeout 은 JS의 대표적인 비동기 함수로 2 개의 인자를 갖는다. 첫 번째는 실행할 코드이며, 두 번째는 지연할 시간이다. 1000 이 1초다. 
  • 위의 출력 결과를 보면 비동기 함수의 특징이 절실하게 드러난다. 시작과 종료가 먼저 출력되고 timer 종료가 이후에 출력되는 것을 볼 수 있다. 

  • 그림으로 비동기 함수 처리 과정을 이해해보자. 

    Call Stack 에 console.log('시작') 이 먼저 들어온다. 

  • 우선 console.log 는 동기 함수이므로 바로 함수가 실행된다. 

  • setTimeout( ) 함수가 Call Stack 영역에 우선 들어온다. 

  • setTimeout( ) 함수는 비동기함수이므로 대기실(background)로 이동하고 대기 하기 시작한다. 

  • 뒤 이어 console.log('종료'); 함수가 Call Stack 에 들어온다. 

  • console.log('종료'); 함수는 동기 함수이므로 즉시 실행된다. 

  • 대기실(background) 에서 대기하고 있던 callback( ) 함수는 timer 시간 3초가 지나면 Callback Queue 영역으로 들어간다. 

  • Call Stack 이 비어있다면 Callback Queue 에 담긴 함수를 Call Stack 으로 불러온다. 

  • Callback Queue 에서 온 비동기함수가 Call Stack 에서 실행되어 처리된다. 


setTimeout(function callback() {
    console.log('첫 번째 타이머 종료');
}, 5000);

setTimeout(function callback() {
    console.log('두 번째 타이머 종료');
}, 0);

setTimeout(function callback() {
    console.log('세 번째 타이머 종료');
}, 3000);
 
  • 위의 출력 결과를 이해해보자

    1 타이머 call stack -> background -> 2 타이머 call stack -> background -> callback queue -> call stack -> 2 타이머 실행 -> 3 타이머 call stack -> back ground -> callback queue -> 3 타이머 실행 -> call back queue -> 5 타이머 실행
    : 총 5초 소모