TIL - 4회차

원종현·2021년 3월 6일
0

TIL

목록 보기
4/7
post-thumbnail

2021.03.06

  • 비동기 처리
  • AJAX

비동기 처리?


특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 자바스크립트의 특성(싱글 스레드, 콜스택)을 의미힌다.

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


자바스크립트 언어는 Single Thread 언어이다. 즉, 이벤트를 처리하는 Call Stack이 하나뿐이다. 따라서, 여러 이벤트를 처리할 때에 동기적으로 처리하게 되면 하나의 이벤트가 모두 처리될 때까지 다른 업무는 수행하지 못하는 현상이 발생한다.

즉, call stack이 하나인 자바스크립트는 한 번에 한 가지만 수행할 수 있는 언어이다.

자바스크립트는 즉시 처리하지 못하는 이벤트들을 Web API로 보내 Call Stack이 비었을 때에 먼저 처리된 이벤트들을 줄세워 다시 이벤트 큐에 넣게 된다.

Javascript Engine은 Memory Heap과 Call Stack으로 이루어져 있다
Memory Heap : js를 사용해 만든 함수, 배열, 객체 등의 저장 공간
Call Stack : 함수 실행 호출이 쌓이는 곳, 호출이 끝나면 사라진다.
구동 순서
Call Stack -> Web API -> Callback Queue -> Event Loop 동작 -> Call Stack
Web API
Call Stack에서 비동기 함수나 setTimeout, setInterval등의 함수의 호출이 있을 때 Web API로 이동한다. 즉, 당장 실행되지 않는 함수들이 호출이 되기를 기다리는 공간이라고 볼 수 있으며 Web API로 이동될 때 Call Stack에서는 호출이 끝난 것으로 간주되어 사라지게 된다.
정해진 시간이 지나면 함수 호출을 위해 Callback Queue로 이동한다.
API로 이동된 순서는 중요하지 않고, 정해진 시간이 짧은 경우에는 Web API에 늦게 들어온 함수라 해도 먼저 Callback Queue로 이동한다.
Callback Queue
Web API에서 전송된 함수들이 단지 줄을 서있는 공간이며 이후 순서가 바뀌지 않는다.(Task Queue, Event Queue라고도 한다.)
Event Loop
Event loop 동작하려면 아래의 두가지 조건이 충족되어야 한다.
1. Callback Queue에 실행해야 할 함수가 있다.
2. Call Stack 이 비어있다. (run to completion)
조건이 충족될 때 Callback Queue 에 있는 함수들을 순서대로 Call Stack으로 이동시켜 해당 함수가 호출되도록 한다.
Run to completion
자바스크립트는 현재 위치한 곳의 함수들의 호출이 끝나야 다음 작업을 실행한다.
비동기 함수가 지정한 시간이나 응답이 완료되어 Callback Queue로 넘어가도 Call Stack이 버어지지 않으면 Event Loop는 동작하지 않는다.
Event LoopCallback Queue 뿐 아니라 render queue, job queue등 여러가지 큐를 관리하고 실행하기 때문에 내가 원하는 정확한 시점에 정확히 Event Loop가 동작하여 함수를 실행하지 않을 수도 있다.

비동기 처리 사례


첫 번째 사례(AJAX)

비동기 처리의 가장 흔한 사례는 ajax이다. 보통 화면에 표시할 데이터를 서버에서 불러와야할 때 ajax통신으로 해당 데이터를 서버로부터 불러올 수 있다.

function loadData() {
  const xhr = new XMLHttpRequest();
  let Data;
  xhr.onreadystatechange = function() {
    if(this.readyState === this.DONE) {
      Data = JSON.parse(this.responseText);
    }
  }
   xhr.open("GET", "https://jsonplaceholder.typicode.com/posts", true);
  xhr.send();
  return Data;
}
console.log(loadData()); //undefined

여기서 HTTP GET 요청을 받아올 때까지 기다리지 않고 다음 코드인 return Data;를 실행 하기 때문에 초기값을 설정하지 않은 Data의 값 undefined를 출력하게 됩니다.
이렇게 특정 로직의 실행이 끝날 때까지 기다리지 않고 나머지 코드를 먼저 실행하는 것이 비동기 처리입니다. 클라이언트가 서버로 데이터를 요청했을 때 서버에서 언제 응답을 줄지도 모르는데 다른 코드를 실행 안 하고 기다릴 순 없기 때문에 JS에서 비동기 처리가 필요합니다.

두 번째 사례(setTimeout())

setTimeout()은 Web API의 한 종류입니다. 코드를 바로 실행하지 않고 지정한 시간이 지나면 로직을 실행합니다.

// #1
console.log('foo');
// #2
setTimeout(function() {
	console.log('bar');
}, 3000);
// #3
console.log('foo bar');
  • 'foo' 출력
  • 'foo bar' 출력
  • 3초 지나고 'bar' 출력
    setTimeout() 역시 비동기 방식이므로 3초를 기다렸다가 다음 코드를 실행하는 것이 아닌 일단 setTimeout()을 실행하고 바로 다음 코드인 console.log('foo bar');를 실행한 후 3초 지났다면 console.log('bar');이 실행됩니다.
    따라서 'foo', 'foo bar'를 먼저 출력하고 3초 후 'bar'가 출력됩니다.

비동기 처리 문제점 해결하기


콜백 함수 사용

function getData(callback) {
  let data;

  setTimeout(function () {
    data = 'result';
    callback(data);
  }, 1000);
}

getData(function (data) {
  console.log(data); // result
});

콜백 함수를 사용하면 특정 로직이 끝났을 때 원하는 동작을 실행시킬 수 있다.

콜백 함수는 나중에 호출할 함수를 의미한다.(파라미터로 함수를 전달하는 함수)

콜백 지옥(Callback hell)

콜백 지옥은 비동기 처리 로직을 위해 콜백 함수를 연속해서 사용할 때 발생하는 문제이다.

step1(function (value1) {
  step2(function (value2) {
    step3(function (value3) {
      step4(function (value4) {
        step5(function (value5) {
          // 탈출
        });
      });
    });
  });
});

서버에서 데이터를 받아와 화면에 표시하기까지 인코딩, 사용자 인증, 등 위 예시처럼 여러 로직을 처리해야 하는 경우가 있다. 이때 모든 과정을 비동기로 처리해야 한다고 하면 위와 같이 콜백 안에 콜백을 계속 추가하는 형태로 코드를 작성하게 된다. 이와 같은 코드 구조를 콜백 지옥이라 한다.

  • 가독성이 떨어진다.
  • 로직 변경이 어렵다.
  • 모든 콜백에서 각각 에러 핸들링을 해주어야 한다.(에러 처리가 필요한 경우)

콜백 지옥 해결 방법

일반적으로 콜백 지옥을 해결하는 방법에는 Promise or Async를 사용하는 방법이 있다.

AJAX


AJAX(Asynchronous Javascript And XML)란, Javascript의 라이브러리 중 하나이다. Asynchronous Javascript And XML(비동기식 자바스크립트 & xml)의 약자로 Javascript를 사용한 비동기 통신, 클라이언트와 서버간에 XML 데이터 통신 기술이다.

브라우저가 갖고 있는 XMLHttpRequest객체를 이용, 전체 페이지를 리로드 하지않고 특정 데이터만 로드하는 기법 쉽게 말해 서버와 통신하기 위해 XMLHttpRequest객체를 사용하는 것을 의미한다.

XML : W3C에서 개발된, 여러 특수 목적의 마크업 언어를 만드는 용도에서 권장되는 다목적 마크업 언어 위키백과

Ajax 사용이유


기본적으로 HTTP 프로토콜은 클라이언트에서 Request를 보내고 서버에서 보낸 Response를 받으면 연결이 끊기게 되어있다. 다시 데이터 통신을 하기 위해서는 request, response 과정을 다시 거치며 페이지 전체를 리로드 해야한다. 이럴 경우 자원낭비와 시간낭비가 발생한다.
Ajax는 HTML 페이지 전체가 아닌 일부분만 리로드할 수 있도록 XMLHttpRequest객체를 통해 서버에 request한다.
JSON이나 XML형태로 필요한 데이터만 받아 갱신하기 때문에 자원과 시간을 아낄 수 있는 장점이 있다.

서버로부터 웹페이지가 반환되면 화면 전체를 갱신해야 하는데 페이지 일부만을 갱신하고도 동일한 효과를 볼 수 있도록 하는 것이 Ajax이다. 페이지 전체를 로드하여 렌더링할 필요가 없고 갱신이 필요한 일부만 로드하여 갱신하면 되므로 빠른 퍼포먼스와 부드러운 화면 표시 효과를 기대할 수 있다.

특징


  • 특징
    1. 웹페이지 속도 향상
    1. 서버의 처리가 완료될 때까지 기다리지 않고 처리 가능(비동기성)
    2. 페이지 새로고침 없이 서버에 요청

AJAX의 진행과정


  1. 사용자에 의해 request 요청 발생
  2. 이벤트 핸들러에 의해 js 호출
  3. XMLHttpRequest객체 생성 및 요청
    • 이때 웹 브라우저는 요청을 보내고, 서버의 응답을 기다릴 필요 없이 다른 작업을 처리할 수 있다.
  4. Ajax 요청 처리
    • 서버는 전달받은 XMLHttpRequest객체를 가지고 Ajax요청 처리
  5. response 생성
  6. HTML, XML, JSON 데이터 전송
    • 서버는 처리한 결과를 HTML, XML, JSON 형태의 데이터로 웹 브라우저에 전달 (전달되는 response는 필요한 데이터만을 전달)
  7. HTML, CSS 데이터 랜더
    • 전달받은 데이터로 웹 페이지 갱신 js 호출 (필요한 일부 html, css 렌더링)
  8. 웹 페이지 일부분만 리로드

AJAX가 쓰이는 방법


XMLHttpRequest 객체를 얻은 뒤, url을 통해 요청하고 응답을 받으면 응답 결과에 맞는 함수를 실행하는 구조로 되어 있다.

profile
프론트엔드 엔지니어를 목표로 공부하는 중입니다!.

0개의 댓글