[2024.04.23] JS 비동기 JS

체리마루·2024년 4월 23일

비동기

  • 동기(Synchronous): 프로그램의 실행 흐름이 순차적으로 진행
    => 하나의 작업이 완료된 후에 다음 작업이 실행되는 방식

  • Synchronous 예시

1)

print('첫번째 작업')
for i in range(10)
	print('메인 작업')
print('마지막 작업')

=> 메인 작업이 모두 수행되어야 마지막 작업이 수행됨

2)

const makeGreeting = function (name) {
	return `Hello my name is ${name}!`
}

const name = 'Alice'
const greeting = makeGreeting(name)
console.log(greeting)

=> 함수의 작업이 완료될 때까지 기다렸다가 값을 반환해야 계속 진행 가능

  • 비동기(Asynchronous): 프로그램의 실행 흐름이 순차적이지 않으며, 작업이 완료되기를 기다리지 않고 다음 작업이 실행되는 방식
    => 작업의 완료 여부를 신경 쓰지 않고 동시에 다른 작업들을 수행할 수 있음

  • Asynchronous 예시
    1)
    Gmail에서 메일 전송 버튼을 누르면 목록 화면으로 전환되지만 실제로 메일을 보내는 작업은 병렬적으로 별도로 처리됨
    2)
    브라우저는 웹페이지를 먼저 처리되는 요소부터 그려 나가며 처리가 오래 걸리는 것들은 별도로 처리가 완료되는대로 병렬적으로 진행
    3)

const slowRequest = function (callBack) {
	console.log('1. 오래 걸리는 작업 시작...')
    // 3초 기다렸다가 콜백 함수를 호출하는 함수 (3초 뒤 출력이 아닌, 3초 뒤에 Task Queue(대기실)로 가겠다는 의미)
    setTimeout(function () {  				
    	callBack()
    }, 3000)
}

const myCallBack = function () {
	console.log('2. 콜백함수 실행됨')
}

slowRequest(myCallBack)

console.log('3. 다른 작업 실행')

// 출력 결과
1. 오래 걸리는 작업 시작...
3. 다른 작업 실행
2. 콜백함수 실행됨

*오래 걸릴 거 같으면 다른 거 먼저 처리하고 돌아옴 (비동기)
  • Asynchronous 특징
    : 병렬적 수행
    : 당장 처리를 완료할 수 없고 시간이 필요한 작업들은 별도로 요청을 보낸 뒤 응답이 빨리 오는 작업부터 처리

JavaScript와 비동기

  • Single Thread 언어, JavaScript
    : JavaScript는 Thread가 한 개 (한 번에 한 개의 작업만 처리 가능)
    : Thread란? 작업을 처리할 때 실제로 작업을 수행하는 주체로, multi-thread라면 업무를 수행할 수 있는 주체가 여러 개라는 의미

  • JavaScript Runtime
    : JavaScript가 동작할 수 있는 환경(Runtime)
    : JavaScript 자체는 Single Thread이므로 비동기 처리를 할 수 있도록 도와주는 환경이 필요
    : JavaScript에서 비동기와 관련한 작업은 브라우저 또는 Node와 같은 환경에서 처리

  • 브라우저 환경에서의 JavaScript 비동기 처리 관련 요소

  1. JavaScript Engine의 Call Stack
  2. Web API
  3. Task Queue
  4. Event Loop


JavaScript는 Call Stack 하나만 갖고 있고, 나머지(Web API, Task Queue, Event Loop)는 브라우저가 처리하는 구역

  • 브라우저 환경에서의 JavaScript 비동기 처리 동작 방식
  1. 모든 작업은 Call Stack(LIFO)으로 들어간 후 처리된다.
  2. 오래 걸리는 작업이 Call Stack으로 들어오면 Web API로 보내 별도로 처리하도록 한다.
  3. Web API에서 처리가 끝난 작업들은 곧바로 Call Stack으로 들어가지 못하고 Task Queue(FIFO)에 순서대로 들어간다.
  4. Event Loop가 Call Stack이 비어 있는 것을 계속 체크하고 Call Stack이 빈다면 Task Queue에서 가장 오래된(가장 먼저 처리되어 들어온) 작업을 Call Stack으로 보낸다.
  • 비동기 처리 동작 요소
  1. Call Stack
    요청이 들어올 때마다 순차적으로 처리하는 Stack(LIFO)
    기본적인 JavaScript의 Single Thread 작업 처리

  2. Web API
    JavaScript 엔진이 아닌 브라우저에서 제공하는 runtime 환경
    시간이 소요되는 작업을 처리 (setTimeout, DOM Event, 비동기 요청 등)

  3. Task Queue (Callback Queue)
    비동기 처리된 Callback 함수가 대기하는 Queue(FIFO)
    Call Stack으로 돌아오기 때문에 Callback 함수라는 이름이 붙음

  4. Event Loop
    테스크(작업)가 들어오길 기다렸다가 테스크가 들어오면 이를 처리하고, 처리할 테스크가 없는 경우엔 잠드는, 끊임없이 돌아가는 자바스크립트 내 루프
    Call Stack과 Task Queue를 지속적으로 모니터링함
    Call Stack이 비어있는지 확인 후 비어 있다면 Task Queue에서 대기 중인 오래된 작업을 Call Stack으로 Push

Ajax

  • Ajax(Asynchronous JavaScript and XML): XMLhttpRequest 기술을 사용해 복잡하고 동적인 웹페이지를 구성하는 프로그래밍 방식
    : 비동기적인 웹 애플리케이션 개발을 위한 기술
    : 브라우저와 서버 간의 데이터를 비동기적으로 교환하는 기술
    : Ajax를 사용하면 페이지 전체를 새로고침하지 않고도 동적으로 데이터를 불러와 화면을 갱신할 수 있음
    : Ajax의 'x'는 XML이라는 데이터 타입을 의미하긴 하지만, 요즘은 더 가벼운 용량과 JavaScript의 일부라는 장점 때문에 'JSON'을 많이 사용함

  • Ajax의 목적
    전체 페이지가 다시 로드되지 않고 HTML 페이지 일부 DOM만 업데이트
    => 웹 페이지 일부가 다시 로드되는 동안에도 코드가 계속 실행되어, 비동기식으로 작업할 수 있음

  • XMLHttpRequest 객체(XHR): 서버와 상호작용할 때 사용하는 객체. 페이지의 새로고침 없이도 데이터를 가져올 수 있음


  • 이벤트 핸들러는 비동기 프로그래밍의 한 형태
    이벤트가 발생할 때마다 호출됟는 함수(콜백 함수)를 제공하는 것
    HTTP 요청은 응답이 올 때까지의 시간이 걸릴 수 있는 작업이라 비동기이며, 이벤트 핸들러를 XHR 객체에 연결해 요청의 진행상태 및 최종 완료에 대한 응답을 받음

Axios

  • Axios: JavaScript에서 사용되는 HTTP 클라이언트 라이브러리
    파이썬에서는 request를 통해 서버 주소로 데이터와 요청을 보냄.
    JavaScript에서는 Axios라는 라이브러리를 통해 서버 주소로 데이터와 요청을 보냄.

  • Axios 정의
    : 클라이언트 및 서버 사이에 HTTP 요청을 만들고 응답을 처리하는데 사용되는 자바스크립트 라이브러리
    : 서버와의 HTTP 요청과 응답을 간편하게 처리할 수 있도록 도와주는 도구
    : 브라우저를 위한 XHR 객체 생성
    : 간편한 API 제공하며, Promise(응답 객체 이름) 기반의 비동기 요청을 처리
    => 주로 웹 애플리케이션에서 서버와 통신할 때 사용


  • Promise object
    자바스크립트에서 비동기 작업을 처리하기 위한 객체
    비동기 작업의 성공 또는 실패와 관련된 결과나 값을 나타냄

  • then & catch
    then(callback)
    : 요청한 작업이 성공하면 callback 실행
    : callback은 이전 작업의 성공 결과를 인자로 전달 받음
    catch(callback)
    : then()이 하나라도 실패하면 callback 실행 (남은 then은 중단)
    : callback은 이전 작업의 실패 객체를 인자로 전달 받음

  • 고양이 사진 가져오기 실습

  • 실습 심화
    cat api로 요청을 보내서 응답을 받은 후, 응답 데이터에서 이미지 주소를 추출하여, HTML img 태그를 생성 후 src 속성 값에 저장하고, 완성된 img 태그를 화면에 출력

  • 정리
    Ajax: 특정한 기술 하나를 의미하는 것이 아니며, 비동기적인 웹 애플리케이션 개발에 사용하는 기술들을 묶어서 지칭
    Axios: 클라이언트 및 서버 사이에 HTTP 요청을 만들고 응답을 처리하는데 사용되는 자바스크립트 라이브러리 (Promise API 지원)
    => 프론트엔드에서 Axios를 활용해 DRF로 만든 API 서버로 요청을 보내서 데이터를 받아온 후 처리하는 로직을 작성하게 됨

Callback과 Promise

비동기 콜백

  • 비동기 처리의 단점
    : 비동기 처리의 핵심은 Web API로 들어오는 순서가 아니라 작업이 완료되는 순서에 따라 처리한다는 것이다. 그런데 이는 개발자 입장에서 코드의 실행 순서가 불명확하다는 단점이 존재한다. 이와 같은 단점은 실행 결과를 예상하면서 코드를 작성할 수 없게 한다.
    => 콜백 함수를 사용하자!

  • 비동기 콜백
    : 비동기적으로 처리되는 작업이 완료되었을 때 실행되는 함수
    : 연쇄적으로 발생하는 비동기 작업을 순차적으로 동작할 수 있게 함
    => 작업의 순서와 동작을 제어하거나 결과를 처리하는데 사용

  • 콜백 지옥(Callback Hell): 비동기 처리를 위한 콜백을 작성할 때 마주하는 문제. 코드 작성 형태가 마치 '피라미드' 같다고 해서 Pyradmid of doom(파멸의 피라미드)라고도 부름

  • 정리
    콜백 함수는 비동기 작업을 순차적으로 실행할 수 있게 하는 반드시 필요한 로직
    비동기 코드를 작성하다 보면 콜백 함수로 인한 콜백 지옥은 빈번히 나타나는 문제이며 이는 코드의 가독성을 해치고 유지보수가 어려워짐
    => 지옥에 빠지지 않는 다른 표기 형태가 필요!

프로미스

  • Promise: JavaScript에서 비동기 작업의 결과를 나타내는 객체
    => 비동기 작업이 완료되었을 때 결과 값을 반환하거나, 실패 시 에러를 처리할 수 있는 기능을 제공
    자바스크리브에서 비동기 작업을 처리하기 위한 객체
    비동기 작업의 성공 또는 실패와 관련된 결과나 값을 나타냄
    콜백 지옥 문제를 해결하기 위해 등장한 비동기 처리를 위한 객체
    '작업이 끝나면 실행시켜 줄게' 라는 약속

  • Promise 기반의 HTTP 클라이언트 라이브러리가 바로 'Axios'
    성공에 대한 약속 then() / 실패에 대한 약속 catch()

  • Axios: JavaScript에서 사용되는 "Promise" 기반 HTTP 클라이언트 라이브러리

  • then & catch의 chaining
    axios로 처리한 비동기 로직은 항상 promise 객체를 반환
    즉, then과 catch는 모두 항상 promise 객체를 반환 => 계속해서 chaining 가능
    then을 계속 이어가면서 작성할 수 있게 됨

  • then 메서드 chaining 적용

    *첫번째 then의 반환값이 다음 then으로 넘어감 (return을 통해)

  • then 메서드 chaining ver.

  • 한 번 더 chaining ver.

profile
멋쟁이 토마토 개발자 🍅

0개의 댓글