[javascript]비동기처리와 Promise/axios/fetch

Grace·2021년 10월 1일
20

javascript

목록 보기
1/2
post-thumbnail

처음 면접을 볼 때는, 자바스크립트의 비동기처리에 대해서 말해달라고 했을 때,
" 특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 자바스크립트의 특성입니다. "
라고만 말하고 끝맺음 해버렸다.
말 그대로 용어에 대한 정의만 알고 있었기 때문에 더 부연해서 설명할 것이 없었따 😭😭
그래서 이번에 제대로 정리해서 이해해두기로 했다..!


자바스크립트의 비동기처리


동기(synchronous)와 비동기(asynchronous)로 작성한 코드의 가장 큰 차이점은
런타임 시 발생하는 지연시간이다.
만약 모든 코드가 동기적으로(순차적으로) 실행된다면,
메세지를 보낸다고 가정했을 때 메세지를 보내고 응답이 오기까지는 다른 작업이 불가능해진다.
앞의 작업(메세지를 보냄)이 끝나지 않았기 때문이다.

물론 동기적으로 작업하게 되면 코드 파악이 쉬워지고 유지보수나 디버깅도 쉬워진다.
하지만 싱글스레드 방식의 자바스크립트에서는 동기적 방식을 사용하면 문제가 많아진다.
때문에 자바스크립트에서는 비동기방식으로 작업이 진행되게 된다.

자바스크립트의 비동기 처리란 특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 자바스크립트의 특성을 의미합니다.
[캡틴판교님의 글 중]

이 특성의 주요한 두가지 사례로 AJAXsetTimeout()를 들 수 있다.

1. AJAX (Asynchronous Javascript And XML)

먼저 ajax는 어떤 언어나 기술이 아니라, 비동기방식의 통신기법을 말한다.

  • 자바스크립트를 이용해 서버와 브라우저가 비동기 방식으로 XML데이터를 교환할 수 있는 통신 기능
  • 데이터를 이동하고 화면을 구성하는데 있어서 전체 페이지를 새로 고치지 않고도 페이지의 일부만을 위한 데이터를 로드하는 기법

따라서 화면 갱신이 없기 때문에,
사용자 입장에서는 빠르고 편리하게 작업이 처리되는 것처럼 느껴진다.

코드로 예를 들어보자면,

function getData() {
  var initData;
  $.get('http://domain.com/products/1', function(response) {
    var initData = response;
  });
  return initData;
}
console.log(getData()); // undefined

getData()를 찍었지만, undefined가 출력되었다.
그 이유는 ajax 통신을 하는 부분인 $.get() 에서
데이터 요청에 대한 응답을 받기도 이전에
다음 코드인 return initData를 실행했기 때문이다.
그래서 getData()의 결과값은
초기에 아무것도 설정하지 않은 값인 undefined가 출력된다.

📍 JQuery의 Ajax라고 불리는 이유?
▶️ 순수 Ajax로 작성할 때보다, JQuery를 사용하여 Ajax를 구현할 경우 브라우저에 구애받지 않고 동일한 코드로 같은 작업을 구현할 수 있기 때문에 좀 더 쉽게 사용이 가능하다.

2. setTimeout( )

두번째 비동기처리의 사례로는 web API의 한 종류인 setTimeout이 있다.

// #1
console.log('Hello');
// #2
setTimeout(function() {
  console.log('Bye');
}, 3000);
// #3
console.log('Hello again');

위의 코드 결과값을 확인해보면

비동기방식으로 실행되는 setTimeout때문에
코드가 위에서부터 순서대로 출력되지 않고,
setTimeout함수 안의 코드는 해당 코드가 실행되고 3초 후에 출력되게 된다.

비동기처리 문제 해결하기

이렇게 비동기 방식으로 처리되는 자바스크립트의 특성 때문에
개발자는 의도적으로 예외처리를 해줘야 하는 상황이 발생하곤 한다.

앞서 보여주었던 코드들를 예로 들자면,
데이터를 다 받아오기도 전에 비동기적인 코드처리 때문에
데이터를 받아온 것 처럼 화면에 표시하려고 하면 오류가 나기 때문이다.

때문에 이런 문제들을 해결하기 위해 콜백(callback)함수를 사용하게 되었다.

CallBack

콜백함수는 자바스크립트의 비동기성을 표현하고 관리하는 가장 일반적인 기법이자 가장 기본적인 비동기 패턴이다
[You don't know Js]

콜백 함수는 코드를 통해 명시적으로 호출하는 함수의 개념이 아니다.
개발자는 단지 함수를 동록하기만 하고, 어떤 이벤트가 발생했거나 특정 시점에 도달했을 때 시스템에서 호출하는 함수를 말한다.
콜백함수는 어떤 문법적 특징을 가지고 있는 것이 아니라, 호출방식에 의한 구분이다.

콜백함수가 실행됐다는 것으로 요청한 작업이 끝났음을 알리고,
작업의 결과물은 콜백함수를 통해 사용 가능하게 된다.
(가장 대표적인 예로는, 이벤트 핸들러 처리)

하지만 콜백을 많이 사용하다보니 문제가 있었다.

  • 순차적 실행이 필요한 경우에 비동기처리를 중첩시켜 표현하기에 에러나 예외 처리가 어려움
  • 중첩으로 인한 복잡도가 증가(=콜백지옥)

이런 단점들을 해결하기 위해 Promise가 라이브러리로 생겨났고,
이후 ES6에서는 언어적 차원에서 지원하게 되었다.

Promise

자바스크립트 비동기를 간편하게 처리할 수 있도록 도와주는 객체(object)이다.
Promise는 정해진 장시간의 기능을 수행한 후,
정상적으로 기능이 수행되었다면 성공의 메세지와 함께 결과값을 전달하고
문제가 발생할 경우엔 에러를 전달해주게 된다.

간단히 말하면,
비동기에서 성공과 실패를 분리해서 메서드를 수행한다. 라고 할 수 있겠다.

순차적이지 않는 비동기함수의 실행순서를 제어할 수 있게 도와주고,
콜백함수에 비해 코드 가독성이 좋고 반환된 결과물을 사용하기 편리한 것이 특징이다.

Axios

Axios is a simple promise based HTTP client for the browser and node.js.
[axios 공식문서]

즉, node.js와 브라우저를 위한 Promise기반의 HTTP통신 라이브러리이다.
비동기로 HTTP 통신을 가능하게 해주며 return을 Promise 객체로 해주기 때문에 response 데이터를 다루기도 쉽다.

기본적인 사용법은 아래와 같다.

const axios = require('axios')

// ID로 사용자 요청
axios
  .get('/user?ID=12345')
  // 응답(성공)
  .then(function(response) {
    console.log(response)
  })
  // 응답(실패)
  .catch(function(error) {
    console.log(error)
  })
  // 응답(항상 실행)
  .then(function() {
    // ...
  })

Fetch

Fetch는ES6부터 JavaScript의 내장 라이브러리로,
서버로 네트워크 요청을 보내고 응답을 받을 수 있도록 해주는 메서드이다.

XMLHttpRequest와 비슷하지만 fetchPromise를 기반이기에
더 간편하게 사용할 수 있다는 차이점이 있다.

📍 XMLHttpRequest가 뭘까
대부분의 웹 브라우저에서는 서버로부터 데이터를 요청하는 XML 객체들을 내장하고 있다. 이름만 보면 XML 데이터만 다룰 수 있을 것 같지만 모든 데이터를 다룰 수 있다.
XMLHttpRequest를 이용하면 웹 페이지를 전부 로딩하고도 서버로부터 데이터를 요청하거나 전송받을 수 있으며, 웹 페이지를 전부 로딩하지 않고도 일부만을 갱신하는 게 가능해진다. ( = AJAX 프로그래밍에서 주로 사용)

기본적인 사용법은 아래와 같다.

fetch(url, options)
  // 응답(성공)
  .then((response) => console.log("response:", response))
  // 응답(실패)
  .catch((error) => console.log("error:", error));

Axios vs Fetch

이전 프로젝트를 진행할 때 fetch를 사용했다가,
코딩테스트를 볼 기회가 생겨서 새롭게 axios를 사용해봤는데
왜들 axios를 쓰라 하는지, 정리를 해두기로 했다ㅎ

AxiosFetch
요청 객체에 url이 있다.요청 객체에 url이 없다.
써드파티 라이브러리로 설치가 필요브라우저에 빌트인이라 설치 필요 없음
data 속성을 사용body 속성을 사용
data는 object를 포함한다body는 문자열화 되어있다
status가 200이고 statusText가 ‘OK’이면 성공이다응답객체가 ok 속성을 포함하면 성공이다
자동으로 JSON데이터 형식으로 변환된다.json()메서드를 사용해야 한다.
요청을 취소하거나 response timeout을 걸 수 있다.해당 기능 존재 하지않음
HTTP 요청을 가로챌수 있음해당 기능 존재 하지않음
download진행에 대해 기본적인 지원을 함해당 기능 존재 하지않음
크로스 브라우징으로 브라우저 호환성이 뛰어남Chrome 42+, Firefox 39+, Edge 14+, and Safari 10.1+이상에 지원

정리하고 보니 Axios는 별도의 라이브러리 설치를 해야한다는 점 이외에는
쓰기 번거로운 이유는 없는 것 같다.
Axios가 대략Fetch의 상위 호환 버전이라고 생각하면 될 것 같다.

그렇기에 많은 사람들이 간단하게 사용할때는 Fetch를 쓰고,
이외의 확장성을 염두해봤을 땐 Axios를 쓰는 것이 좋다고들 말하는 것 같다.


단기간내에 실제 개발을 위한 개념들을 익히고 적용시키는 것과
알아야 하는 문법들이나 개념들을 머릿속에 적립한다는게 꽤나 쉬운 일이 아닌 것 같다.
그래서 다발적으로 여기저기서 쏟아지는 단어들에 대한 개념과
그 단어들 각자의 관계성을 이해하는데에는 계속해서 정리가 필요할 것 같다.

이번 포스팅의 비동기처리에 대해서는 이정도로 정리할 수 있을 것 같다.
도식화를 하고 싶었는데 올바른 정보 정리를 위해서는 좀 더 공부해야할 것 같다.
이쯤에서 잠 확 깨는 짤 투척

이번 포스팅에서 중구남방으로 알았던 각 단어들에 대한 개념과
관계성에 대해서만 정리하도록 하고,
좀 더 정리가 필요한 Promise, 더 나아가 async & await 에 대해서는
따로 정리를 해야 할 것 같다.

누군가가 보고 계시다면,
그리고 혹시나 수정해야 할 부분이 있다면 댓글로 알려주시면 감사하겠습니다!

📌 참고하였습니다 :)

profile
쉽게 사는건 재미가 없더군요, 새로 시작합니다🤓

2개의 댓글

comment-user-thumbnail
2022년 7월 31일

도움 많이 되었습니다!

1개의 답글