[Javascript] 동기와 비동기에 대하여

시작하는 개발일지·2021년 4월 5일
0

Javascript

목록 보기
1/2
post-thumbnail

1. 동기(Synchronous)와 비동기(Asynchronous)

  • 동기와 비동기의 개념과 용도에 대해서 알아본다.

동기식 처리 방식 : 요청을 보내고 응답을 받은 후에 다음 동작을 실행한다.
비동기식 처리방식 : 요청을 보내고 응답에 관계 없이 다음 동작을 실행한다.

동기식 처리 방식

  • 직렬적인 처리 방식
  • 태스크(task)는 순차적으로 실행되고, 어떤 작업이 수행 중이면 다음 작업은 대기하게 된다.
  • ex) 서버에서 데이터를 가져와 화면에 뿌려주는 작업을 수행할 때, 서버에 데이터를 요청하고 데이터가 응답할 때까지 이후의 태스크들은 블로킹(blocking, 작업 중단)된다.

아래의 코드는 A → B → C 순으로 출력된다.

function func1() {
  console.log('A');
  func2();
}
function func2() { 
  console.log('B');
  func3();
} 
function func3() {
  console.log('C');
}
func1();

비동기식 처리 방식

  • 병렬적인 처리 방식
  • 태스크(task)의 수행이 종료되지 않았더라도 다음 태스크를 실행한다.
  • javascript의 대부분의 DOM 이벤트와 Timer함수(setTimeout, setInterval), Ajax 요청은 비동기식 처리 모델로 동작한다.
  • ex) 서버에서 데이터를 가져와서 화면에 표시하는 태스크를 수행할 때, 서버에 데이터를 요청하고 서버로부터 응답을 받을때까지 대기하지 않고(Non-Blocking) 즉시 다음 태스크를 수행한다. 이후에 서버로부터 데이터를 응답받으면 이벤트가 발생하고 이벤트 핸들러가 데이터를 가지고 수행할 태스크를 계속해 수행한다.

아래의 코드에서 setTimeout 메소드는 비동기 함수이므로 interval이 0이어도 A → C → B 순으로 출력된다.

function func1() {
  console.log('A');
  func2();
}
function func2() { 
  setTimeout(function() {
    console.log('B');
  }, 0);
  func3();
} 
function func3() {
  console.log('C');
}
func1();
  1. func1 메소드가 Call Stack에 쌓인다.
  2. func2 메소드가 호출되면서 Call Stack에 쌓인다.
  3. setTimeout 메소드가 호출되면서 Call Stack에 쌓인다.
  4. 브라우저에서 제공하는 API인 Web APIsCall Stack의 setTimeout 메소드가 비동기임을 확인하고 Web APIs로 이동시킨 뒤 setTimeout 메소드 내부의 Run함수를 호출한다.(타이머 시작)
  5. func3 메소드가 호출되면서 Call Stack에 쌓인다.
  6. setTimeout에서 지정한 시간(interval)이 끝나면, 'tick'이벤트가 발생하면서 Event Queue 로 콜백함수가 이동한다.
  7. 콜백함수는 Call Stack이 비면 Call Stack으로 이동하고, 실행된다.

2. 비동기 처리의 문제점과 해결법

  • 비동기 처리 방식의 문제점을 확인한다.
  • 비동기 흐름을 동기식으로 컨트롤할 수 있는 해결책을 알아본다.

문제점

비동기 처리의 가장 대표적 사례가 jQuery의 ajax이다.
아래의 jQuery ajax 비동기 통신 예제를 살펴보자.
ajax를 통해 특정 url에 HTTP GET 방식으로 데이터를 요청하고 받아온 응답을 출력하려고 한다.

function getData() {
 var tableData;
 $.get('url', function (response) {
  tableData = response;
 })
 // $.get()로 데이터를 요청하고 받아올 때까지 기다리지 않고 return 
 return tableData; 
}
console.log(getData()); //undefined

그러나 의도와 다르게 getData()의 결과값, 즉 tableData는 undefined 를 갖는다.
∵ getData()를 호출하고 특정 서버(url)로의 요청에 대한 응답(response)을 받기도 전에 return 해버렸기 때문이다.
return tableData;가 먼저 실행되었기때문에 getData 메소드는 원하는 응답을 tableData에 담아오지도 못하고 종료된다.

⇒ 이 문제를 해결하려면 tableData = response; 가 실행 될 때까지 return tableData; 가 대기하도록 만들어야 한다.
⇒ 즉, 해결책은 비동기를 동기적인 흐름으로 다루는 것!

해결법

해결법 3가지를 살펴본다.
1. 콜백함수 이용
2. Promise 이용
3. async/await 이용

구체적인 내용은 다음 포스팅에서 알아본다.


Reference

0개의 댓글