[JavaScript] 동기 / 비동기 통신에 관하여

흩날리는추억·2023년 11월 30일

들어가기 전

JavaScript 작동 원리에 대해 공부하며 글을 올린 적이 있습니다. Web APIs를 설명하며 '비동기 처리'라는 단어를 사용하였고, '글이 길어지니 다른 글에서 자세히 설명하겠다.'라고 적었습니다. 시간이 흘러 최근 기본기를 다지고 있는 상황에서 이보다 좋은 기회가 없을거 같아 글을 작성하게 되었습니다. 아래는 제가 예전에 쓴 글입니다.

자바스크립트 동작 원리 1

자바스크립트 동작 원리 2

동기와 비동기에 대해

동기와 비동기는 웹 브라우징, 서버 통신, 사용자 인터페이스 등 많은 프로그래밍 환경에서 중요한 역할을 합니다.

동기(Synchronous) 통신

  • 동기 통신의 개념
    동기 통신이란 요청과 응답이 순차적으로 이루어지는 통신 방식을 의미 즉, 작업이 완료될 때까지 다음 작업이 대기 상태에 머무르는 것
  • 동기 통신의 특징
  1. 요청과 응답이 순차적으로 이루어진다는 점
  2. 한 요청이 끝나기를 기다리는 동안 다른 작업을 수행할 수 없기 때문에 효율성이 떨어질 수 있음
  • 장점
  1. 설계가 매우 간결하고 직관적
  2. 요청과 응답의 순서를 보장
  • 단점
  1. 전체 페이지를 다시 로딩하기 때문에 서버와의 통신량 증가
  2. 결과가 주어질 때까지 대기

비동기(Asynchronous) 통신

  • 비동기 통신의 개념
    요청을 보낸 후 응답을 기다리는 동안 다른 작업을 할 수 있도록 설계된 통신 방식으로 이를 통해 사용자 경험을 향상시키고, 애플리케이션의 효율성을 높임
  • 비동기 통신의 필요성
    동기 통신을 사용하여 서버로부터 데이터를 가져온다면, 이 작업이 끝날 때 동안 사용자는 다른 작업을 하지 못하게 되므로 효율성이 떨어짐
    => ex) 동기 통신이면 유튜브를 보며 인터넷 쇼핑을 하지 못함
  • 장점
  1. 서버와의 통신량이 줄어들고, 자원과 시간을 절약
  2. 요청을 보낸 후 응답을 기다리는 동안 다른 작업 진행
  3. 전체 페이지를 다시 로딩하지 않고 필요한 부분만 업데이트
    => 웹페이지의 속도와 성능을 향상
  • 단점
  1. 코드를 작성하고 이해하는 것이 어려워 코드의 복잡도가 증가
  2. 요청과 응답의 순서를 보장할 수 없음

JavaScript 비동기 통신

JavaScript에서는 여러가지 방법으로 비동기 통신을 할 수 있습니다.
아래의 순서는 출시된 시간 순입니다.

XMLHttpRequest(XHR)

  • 클라이언트가 서버와 데이터를 교환할 수 있게 해주는 JavaScript의 내장 객체
  • AJAX(Ajax) 기술의 핵심 구성 요소 중 하나

AJAX(Asynchronous JavaScript And XML)

  • XMLHttpRequest 객체를 사용하여 서버와 통신
  • XML을 포함하여, JSON, HTML, 텍스트 등 다양한 데이터 형식을 지원
const xhr = new XMLHttpRequest(); // XMLHttpRequest 객체를 생성
// 서버에 요청을 보내기 위해 open() 메소드를 사용
xhr.open("GET", "https://api.example.com/data", true);
xhr.onreadystatechange = function () {
  if (xhr.readyState == 4 && xhr.status == 200)
    console.log(xhr.responseText);
}
xhr.send(); // send() 메소드를 사용하여 실제 요청을 서버에 전송```

콜백함수

  • 함수의 인자로 다른 함수를 받아서 작업이 완료되면 해당 함수를 실행하는 방식
  • 해당 함수의 내부에서 실행되며, 특정 동작이 완료된 후에 호출되는 경우가 대부분
  • 콜백 함수는 여러 개의 비동기 작업을 연결하는 경우 콜백 지옥(Callback Hell)이라는 문제를 일으킬 수 있음
function greet(name, callback) {
  console.log('Hello ' + name);
  callback();
}

greet('Jang', function() {
  console.log('This is a callback function');
});```

Promise

  • JavaScript에서 비동기 연산을 표현하는 객체
  • 비동기 연산이 완료(fulfilled)되거나 거부(rejected)될 때까지 대기(pending) 상태를 유지
const promise = new Promise(function(resolve, reject) { // new Promise를 통해 객체를 생성
  setTimeout(function() {
    const isSuccess = Math.random() >= 0.5; // 무작위로 성공/실패를 결정
    if (isSuccess) {
      resolve("Success!");
    } else {
      reject("Failure!");
    }
  }, 1000);
});

promise
  .then(function(result) { // then() 통해 연산이 성공했을 때 콜백 함수 등록
    console.log(result);
  })
  .catch(function(error) { // catch() 통해 연산이 실패했을 때의 콜백 함수 등록
    console.error(error);
  })
  .finally(function() { // 연산의 성공 여부와 상관없이 항상 실행할 콜백 함수 등록
    console.log('Promise was settled (fulfilled or rejected).');
  });```

Fetch

  • 네트워크 요청을 쉽게 할 수 있도록 제공하는 JavaScript의 내장 함수
  • Promise 기반의 API로 설계되어 있어 간편하게 비동기 처리
fetch('https://api.example.com/data') // fetch() 함수는 지정된 URL에 대한 HTTP 요청
  .then(response => response.json()) // response 객체의 json() 호출하여 응답 본문을 JSON 형식으로 파싱
  .then(data => console.log(data)) // 다시 then() 메서드를 사용하여 파싱된 데이터를 받아 처리
  .catch(error => console.error('Error:', error)); ```

async/await

  • Promise를 더욱 쉽게 사용할 수 있도록 도움
  • 비동기 코드를 마치 동기 코드처럼 작성할 수 있어 가독성 향상
  • 에러 처리를 더 쉽게 할 수 있음

async는 함수 앞에 위치하며, 이 함수는 항상 Promise를 반환
await는 async 함수 내부에서 Promise 앞에 위치하며, Promise의 완료를 기다림
try/catch 문을 사용하여 성공 및 에러 상황 처리할 수 있음

async function fetchData() {
 try {
   const response = await fetch('https://api.example.com/data');
   const data = await response.json();
   console.log(data);
 } catch (error) {
   console.error('Error:', error);
 }
}
fetchData();
profile
걱정보다 생각을 하고 싶은 사람

0개의 댓글