학습을 목적으로 Medium에서 읽은 글을 번역한 글입니다.
번역이 완벽하지 않을 수 있고,
직역하기보다는 문맥에 맞추어 자연스럽게 정리하려고 했습니다.
오류나, 개선하면 좋을 부분들에 대한 피드백은 언제나 환영합니다.😁

 

Async Nature of Javascript

만약 자바스크립트를 알게 된지 얼마되지 않았다면 자바스크립트는 비동기적 언어라는 말을 들어보았을 것이다.

 

하지만 만약 당신이 들은 것이 틀렸고, 자바스크립트는 비동기적 언어가 아니라 동기적으로 작동하는 언어라면?

그렇다면 왜 사람들은 자바스크립트가 비동기적이라고 이야기 하는 걸까?

 

래의 글을 읽어보면서 이해해보자.


📌 what is Synchronous Javascript?

 

만약 작성한 코드가 위에서부터 아래로 순서대로 실행된다면 이것은 동기적으로 작동하는 코드이다.
각각의 라인이 실행하는 작업은 이전 단계의 코드가 완료될 때까지 기다리게 된다.
아래의 예제를 보자 

const add = (a, b) => {
  const sum = a + b;
  return sum;
};

const getSum = add(2, 3);
console.log(getSum)
//5

//Fig 1. A synchronous function to calculate the sum of two number


Fig1을 통해 해당 코드가 어떻게 동작하는 지 알 수 있다. 

  1. const getSum = add(2, 3) 을 실행하게된다.
  2. 첫번째 줄에서 정의한 add함수를 호출하게된다.
  3. a와 b에 해당하는 변수의 합을 상수 sum이라는 변수명으로 저장한다.
  4. 변수명 sum으로 반환된 값을 상수 getSum이라는 변수명으로 저장한다.
  5. 마지막으로 getSum에 할당된 값을 출력한다.

 

위의 결과를 통해 마지막줄의 console.log가 함수 실행 후 결과를 반환할 때까지 기다린다는 사실을 알 수 있다. 


자바스크립트가 위의 순서대로 작동하는 이유는 자바스크립트는 싱글쓰레드이기 때문이다.
싱글쓰레드는 한 시점에서 단 하나의 작업만 실행할 수 있기 때문에 이전 단계의 작업이 완료되기 전까지 다른 작업들은 차단된다.


📌 what is Synchronous Javascript?

 

코드를 작성할 때 특정 단계에서 이전 단계의 완료를 기다리지 않고 실행되는 것을 비동기적 동작이라고 한다. 
이러한 동작은 외부기기에서 데이터를 불러오기 위해 api 콜을 실행할 때 일어나게 되는데, 
이는 모든 데이터를 불러오기 전까지 다른 작업을 실행하지 못하도록 차단하는 것은 의미가 없기 때문이다.
아래의 예제를 보자

const add = (a, b) => {
  const sum = a + b;
  setTimeout(() => {
    console.log(`The sum of ${a} and ${b} is ${sum}`);
  }, 3000);
  return sum;
};

const getSum = add(2, 3);
console.log(getSum);
//5
//The sum of 2 and 3 is 5

//Fig 2. An asynchronous function setTimeout which prints the sum after 3s.


Fig2의 예제에서 위 코드의 결과는 어떻게 나오게 될까?
‘The sum of 2 and 3 is 5’  라는 글자가 sum값보다 먼저 출력될까, 아니면 나중에 출력될까?
코드의 실행순서는 이렇다.

  1. const getSum = add(2, 3)을 실행한다.
  2. 첫번째줄의 add함수를 호출한다.
  3. a와 b의 합이 상수 sum변수명으로 저장된다.
  4. setTimeout은 즉시 실행되지 않고 브라우저로 전송되는데, 일단 실행되면 정의한 callback 함수를 이벤트 큐에 전달한다.
  5. sum값을 반환하고 반환된 값을 상수 getSum변수명으로 저장한다. 
  6. 마침내 getSum변수명의 값을 출력한다. 
  7. 이 후 콜스택이 비게 되면 callback 함수를 메인 쓰레드에 할당하여 3초 후 ‘The sum of 2 and 3 is 5’ 을 출력한다. 

 

위의 상황을 볼때 왜 ‘The sum of 2 and 3 is 5’은 getSum의 값인 5보다 빠르게 호출 되었음에도 불구하고

더 늦게 출력됐을까?


왜냐하면 콜 스택이 비어야 다음 단계를 실행하는 비동기적 콜을 실행하는 이벤트 큐와 이벤트 루프의 개념이 

존재하기 때문이다.


📌 what is Event Queue and Event Loop?

 

비동기 호출은 다음 자바스크립트 코드의 실행을 막지 않기 위해 콜스택이 비게 된 후에,

즉 메인 쓰레드의 작업이 모두 끝난 후에 동작을 실행하게 되는 이벤트 큐 혹은 콜백 큐에 호출된 작업을 전달하게 된다.

Fig 3. How Event loop and Callback Queue works in JS Engine


Fig3에서 콜백 큐에 전달된 이벤트들은 내부에서 모든 코드가 실행된 후에 메인 쓰레드로 전달되어 실행되게 되고

이벤트 큐의 요소들은 이벤트 루프의 도움을 받아 메인쓰레드로 전달된다. 

 

이벤트 루프는 지속적으로 메인쓰레드와 이벤트 큐를 체크하면서 메인 쓰레드가 비게 되면 이벤트 큐의 요소들을 

콜 스택으로 전달한다.


📌 conclusion

위에서 읽어 보았듯이 자바스크립트는 싱글 쓰레드로 동작하는 동기적 언어이다. 


외부 api 이용시 이벤트 큐와 이벤트 루프의 개념을 활용하여 자바스크립트가 비동기적으로 동작하게 한다.


이러한 요소들은 자바스크립트 언어 자체가 아닌 자바스크립트 엔진에 의해 통제되는데

가장 대표적인 자바스크립트 엔진으로는 V8이 있다.


원문

https://ankitsinghania1993.medium.com/async-nature-of-javascript-d3afb71b1c72

 

Async Nature of JavaScript

Well! It will sound odd, that actually JavaScript is not asynchronous it is a synchronous language, then why is everyone saying it is…

ankitsinghania1993.medium.com


+ Recent posts