본문 바로가기
PROGRAMMING/JavaScript

[JS] AJAX, Concurrency model, Promise, Axios

by 안녕나는현서 2021. 11. 14.
728x90

AJAX (Asynchronous JavaScript And XML; 비동기식 JavaScript와 XML)

  • 서버와 통신하기 위해 XMLHttpRequest 객체 활용
    • 서버와 상호작용하기 위해 사용되며 전체 페이지의 새로고침 없이 데이터 받아올 수 있음
    • XML뿐만 아니라 모든 종류의 데이터 받아올 수 있음
  • JSON, XML, HTML, 텍스트 형식 등을 포함한 다양한 포맷 주고 받을 수 있음
  • 페이지 전체를 reload(새로고침) 하지 않고서도 수행되는 비동기성
    • 사용자의 event가 있으면 전체 페이지가 아닌 일부분만을 업데이트
    • 페이지 새로고침 없이 서버에 요청 → 서버로부터 데이터받고 작업 수행

 

동기식

  • 순차적, 직렬적 Task 수행
  • 요청 보낸 후 응답 받아야만 다음 동작 이루어짐 (blocking)
  • 왜 이런 현상이 발생할까? → JS는 single threaded

 

비동기식

  • 병렬적 Task 수행
  • 요청 보낸 후 응답을 기다리지 않고 다음 동작이 이루어짐 (non-blocking)
  • 왜 이런 현상이 발생할까? → JS는 single threaded
  • 왜 비동기를 사용하는가? → 사용자 경험
    • 동기식 코드는 데이터를 모두 불러온 뒤 앱 실행 → 앱이 멈춘 것처럼 보임
    • 비동기식 코드는 데이터를 요청하고 응답 받는 동안 앱 실행을 함께 진행
    • 데이터를 불러오는 동안 지속적으로 응답하는 화면을 보여줌으로써 더욱 쾌적한 사용자 경험 제공

 

Concurrency model

  • Event loop를 기반으로 하는 동시성 모델

 

- Threads

  • 프로그램이 작업을 완료하기 위해 사용할 수 있는 단일 프로세스
  • 각 스레드는 한 번에 하나의 작업만 수행할 수 있음
  • 컴퓨터 CPU는 여러 개의 코어를 가지고 있기 때문에 한 번에 여러 가지 일 처리 가능

 

- JS는 single threaded

  • 컴퓨터가 여러 개의 CPU를 가지고 있어도 main thread라 불리는 단일 스레드에서만 작업 수행
  • == 이벤트를 처리하는 Call stack이 하나
  • 이를 해결하기 위한 concurrency model

 

- Call Stack

  • 요청이 들어올 때마다 해당 요청을 순차적으로 처리하는 Stack(LIFO)

 

- Web API (Browser API)

  • JS 엔진이 아닌 브라우저 영역에서 제공하는 API
  • setTimeout, DOM event, AJAX로 데이터를 가져오는 등 시간이 소요되는 일들을 처리

 

- Task Queue (Event Queue, Message Queue)

  • 비동기 처리된 콜백함수가 대기하는 Queue(FIFO)
  • main thread가 끝난 후 실행되어 후속 JS코드가 차단되는 것 방지

 

- Event Loop

  • Call Stack이 비어있는 지 확인
  • 비어 있다면, Task Queue에서 실행 대기 중인 콜백함수 중 가장 앞에 있는 콜백함수를 Call Stack으로 push

 

* Concurrency Model 이해하기 

 

http://latentflip.com/loupe/?code=JC5vbignYnV0dG9uJywgJ2NsaWNrJywgZnVuY3Rpb24gb25DbGljaygpIHsKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gdGltZXIoKSB7CiAgICAgICAgY29uc29sZS5sb2coJ1lvdSBjbGlja2VkIHRoZSBidXR0b24hJyk7ICAgIAogICAgfSwgMjAwMCk7Cn0pOwoKY29uc29sZS5sb2coIkhpISIpOwoKc2V0VGltZW91dChmdW5jdGlvbiB0aW1lb3V0KCkgewogICAgY29uc29sZS5sb2coIkNsaWNrIHRoZSBidXR0b24hIik7Cn0sIDUwMDApOwoKY29uc29sZS5sb2coIldlbGNvbWUgdG8gbG91cGUuIik7!!!PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D

 

latentflip.com

 

- Runtime

  1. 함수를 동기 호출하면 Call Stack에 차례대로 쌓여서 순서대로 실행
  2. 이 때 setTimeout, DOM event, AJAX가 실행되면 Web API로 이동
  3. Web API에서 처리가 완료되면 Task Queue로 이동
  4. Call Stack이 모두 비게 되면 Event Loop에 의해 Task Queue의 맨 앞의 콜백함수가 Call Stack으로 이동

 

- Zero delays

  • setTimeout에서 0ms로 설정했다고 실제로 0ms 후에 콜백함수가 시작되는 것은 아님
  • Task Queue에 대기 중인 작업 수에 따라 다름
  • delay는 JS가 요청을 처리하는 데 필요한 최소 시간 (보장된 시간이 아님)

 

- 순차적인 비동기 처리

  • Web API로 들어오는 순서는 중요하지 않고 어떤 이벤트가 먼저 처리되느냐가 중요 (실행 순서 불명확)
  • 이를 해결하기 위해 순차적 비동기 처리를 위한 2가지 작성 방식
  • Async callbacks
    • 백그라운드에서 실행을 시작할 함수를 호출할 때 인자로 지정
    • ex) addEventListner() 에서 두 번째 인자
  • promise-style

 

Callback Function

  • 다른 함수에 인자로 전달된 함수
  • 동기식, 비동기식 모두 사용됨 (비동기 작업 완료 후 코드 실행을 계속하는 데 주로 사용 → 비동기 콜백)

 

- Async callbacks (비동기 콜백)

  • 백그라운드에서 코드 실행을 시작할 함수를 호출할 때 인자로 지정된 함수
    • 함수의 참조를 인수로 전달할 뿐, 즉시 실행 x
    • 함수의 body에서 called back 됨
  • 백그라운드 코드 실행이 끝나면 callback 함수를 호출하여 작업이 완료되었음을 알리거나, 다음 작업 실행
  • callback 함수는 명시적인 호출이 아닌 특정 루틴 혹은 action에 의해 호출되는 함수
  • 비동기 로직을 수행할 때 callback 함수는 필수

 

- Callback Hell (콜백 지옥)

  • 순차적인 연쇄 비동기 작업 처리를 위해 callback 함수 호출이 지속적으로 반복
  • 디버깅이 힘들고 코드 가독성 떨어짐
  • 해결 방법
    • Keep your code shallow (코드의 깊이를 얕게 유지)
    • Modularize (모듈화)
    • Handle every single error (모든 단일 오류 처리)
    • Promise callback (Promise 콜백 방식 사용)

 

Promise

  • 비동기 작업의 최종 완료 또는 실패를 나타내는 객체
  • 미래의 완료 또는 실패와 그 결과 값

 

- .then(callback)

  • 이전 작업(Promise)이 성공했을 때 수행할 작업 나타내는 callback 함수
  • 각 callback 함수는 이전 작업의 성공 결과를 인자로 전달받음
  • 각각의 .then() 블록은 서로 다른 promise 반환 → .then()을 여러 개 사용하여 연쇄적인 작업 수행 가능

 

- .catch(callback)

  • .then이 하나라도 실패하면 동작
  • 이전 작업의 실패로 인해 생성된 error객체를 catch 블록 안에서 사용할 수 있음

 

- .finally(callback)

  • Promise 객체 반환
  • 결과와 상관없이 무조건 실행, 무조건 실행되어야 하는 절에서 사용
    • .then() 과 .catch() 블록에서의 코드 중복 방지
  • 어떠한 인자도 전달받지 않음

 

Axios

  • 브라우저를 위한 Promise 기반의 클라이언트

 

// XMLHttpRequest

const request = new XMLHttpRequest()
const URL = 'http:// ~~~~'

request.open('GET', URL)
request.send()

const response = request.response
console.log(response)
// Axios

const URL = 'http:// ~~~~'

axios.get(URL)
  .then(response => {
    console.log(response.data)
  })
728x90

'PROGRAMMING > JavaScript' 카테고리의 다른 글

[JS] 배열 관련 메서드  (0) 2021.11.12
[JS] 함수  (0) 2021.11.12
[JS] 조건문, 반복문  (0) 2021.11.12
[JS] 식별자, 변수, 타입, 연산자  (0) 2021.11.12
[JS] DOM 조작 (선택, 변경)  (0) 2021.11.12

댓글