비동기적인 웹 애플리케이션 개발을 위한 핵심 기술
무언가 일어났다는 신호 ⇒ 웹 상에서 어떻게 구현할까?
querySelector)addEventListener로 요소와 이벤트 핸들러를 연결event: 콜백함수에 첫 번째 파라미터로 전달됨 (이벤트에 대한 정보가 담겨짐)event.target: 이벤트가 발생한 원본 지점event.currentTarget: 실제로 지금 이벤트가 발생하고 있는 지점ctrl + c ⇒ 복사 ⇒ copy 이벤트 ⇒ 복사 안됨form 제출 ⇒ submit ⇒ 새로고침도 막을 수 있다.프로그램의 실행 흐름이 순차적으로 진행되는 방식
(하나의 작업이 완료된 후 다음 작업이 실행되는 방식)
// 동기 예시 코드
console.log('작업 1 시작')
const syncTask = function () {
for (let i = 0; i < 1000000000; i++) {
// 반복 실행 동안 잠시 대기
}
return '작업 완료'
}
const result = syncTask()
console.log(result)
console.log('작업 2 시작')
특정 작업의 실행이 완료될 때까지 기다리지 않고 다음 작업을 즉시 실행하는 방식
(한 작업의 완료 여부를 기다리지 않고, 다른 작업을 동시에 수행할 수 있는 방식)
브라우저는 웹페이지를 먼저 처리되는 요소부터 그려 나가며, 처리가 오래 걸리는 것들은 별도로 처리가 완료 되는 대로 병렬적으로 진행
console.log('작업 1 시작')
const asyncTask = function (callBack) {
setTimeout(() => {
callBack('작업 완료')
}, 3000)
}
asyncTask((result) => {
console.log(result)
})
console.log('작업 2 시작')
// 출력결과
// 작업 1 시작
// 작업 2 시작
// 작업 완료
| 구분 | Synchronous (동기) | Asynchronous (비동기) |
|---|---|---|
| 작업 처리 방식 | • 시작 순서대로 처리 • 앞의 작업이 먼저 끝나야만 다음 작업을 시작할 수 있음 | • 병렬적 수행 • 당장 처리를 완료할 수 없는 작업들은 백그라운드에서 실행되며 빨리 완료되는 작업부터 처리 |
| 장점 | • 단순하고 예측 가능한 흐름 | • 시간이 오래 걸리는 작업을 백그라운드에 위임해 효율성 증가 • 프로그램이 멈추지 않아 사용자 경험(UX) 향상 |
| 단점 | • 시간이 오래 걸리는 작업이 실행되면, 해당 작업이 끝날 때까지 프로그램 전체가 멈춤 • 시스템 자원의 낭비 | • 작업의 시작 순서와 완료 순서가 다를 수 있어, 복잡한 흐름과 결과값을 처리해야 하므로 코드의 복잡성 증가 |
JS는 한 번에 하나의 일만 수행할 수 있는 Single Thread 언어라 동시에 여러 작업 처리가 불가능하다.
그럼 어떻게 비동기 처리를 할까? 🤔
비동기적인 웹 애플리케이션 개발을 위한 기술
Ajax는 웹 페이지 전체를 새로고침하지 않고, 백그라운드에서 서버와 데이터를 주고받는 비동기 통신 기술이다.
구글 지도 앱을 움직여도 끊김이 없고, '좋아요'를 눌렀을 때 페이지만 부분적으로 바뀌는 것이 가능하다. 즉, 웹 페이지를 데스크톱 애플리케이션처럼 동적이고 반응적으로 만들어주는 현대 웹의 핵심 기술 중 하나이다.
XMLHttpRequest 기술을 사용해 복잡하고 동적인 웹 페이지를 구성하는 방식Ajax의 'X'는 원래 XML을 의미했지만, 현재는 더 가볍고 JavaScript에서 다루기 쉬운 JSON 형식을 주로 사용
이름에 XML이라는 데이터 타입이 들어가긴 하지만 XML 뿐만 아니라 모든 종류의 데이터를 가져올 수 있음
➤ 새로운 페이지를 받는 것이 아닌 필요한 부분의 데이터만 받아 기존 페이지의 일부를 수정 (새로고침 X)
➤ 서버에서 모두 처리되던 데이터 처리의 일부분이 이제는 클라이언트 쪽에서 처리되므로 교환되는 데이터양과 처리량이 줄어듦
Client ──── XHR 객체 생성 및 요청 ───> Server
<───────── JSON ─────────────
➤ 주로 웹 애플리케이션에서 서버와 통신할 때 사용
XHR 객체 생성 및 요청 → 응답 데이터 생성 → JSON 데이터 응답 → Promise 객체를 활용해 DOM 조작
(웹 페이지의 일부분 만을 다시 로딩)
CDN 방식으로 사용하기 (https://axios-http.com/)
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
axios({
method: 'get',
url: 'https://api.thecatapi.com/v1/images/search'
})
.then((response) => {
console.log(response)
console.log(response.data)
})
.catch((error) => {
console.error(error)
})
const promiseObj = axios({
method: 'get',
url: 'https://api.thecatapi.com/v1/images/search'
})
console.log(promiseObj) // Promise object
then() : 작업이 성공적으로 완료되었을 때 실행될 콜백 함수를 지정catch() : 작업이 실패했을 때 실행될 콜백 함수를 지정💡 콜백 함수: 다른 함수의 인자로 넘겨지는 함수
promiseObj
.then((response) => {
console.log(response) // Response object
console.log(response.data) // Response data
})
.catch((error) => {
console.error(error)
})
<!-- axios.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
// 1.
const promiseObj = axios({
method: 'get',
url: 'https://api.thecatapi.com/v1/images/search'
})
console.log(promiseObj) // Promise object
promiseObj
.then((response) => {
console.log(response) // Response object
console.log(response.data) // Response data
})
.catch((error) => {
console.error(error)
})
// // 2.
// axios({
// method: 'get',
// url: 'https://api.thecatapi.com/v1/images/search'
// })
// .then((response) => {
// console.log(response)
// console.log(response.data)
// })
// .catch((error) => {
// console.error(error)
// })
</script>
</body>
</html>
then 메서드를 사용해서 "성공했을 때 수행할 로직"을 작성then(callback)catch 메서드를 사용해서 "실패했을 때 수행할 로직"을 작성catch(callback)then()이 하나라도 실패하면 callback 실행 (남은 then은 중단)axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
})
.then(콜백함수)
.catch(콜백함수)
| Ajax | Axios |
|---|---|
| 하나의 특정한 기술을 의미하는 것이 아니라, 비동기적인 웹 애플리케이션 개발에 사용하는 기술들의 집합을 지칭 | 클라이언트 및 서버 사이에 HTTP 요청을 만들고 응답을 처리하는 데 사용되는 자바스크립트 라이브러리 |
| 개념이자 접근 방식 | Promise API를 기반으로 하여 비동기 처리를 더 쉽게 할 수 있음 |
| 실현하는 구체적인 도구 | |
| XMLHttpRequest를 추상화하여 더 사용하기 쉽게 만든 라이브러리 |
💡 비동기: 하나의 작업이 끝날 때까지 기다리지 않고, 다른 작업을 실행
➤ 작업의 순서와 동작을 제어하거나 결과를 처리하는 데 사용
const asyncTask = function (callBack) {
setTimeout(function () {
console.log('비동기 작업 완료')
callBack()
}, 2000)
}
asyncTask(function () {
console.log('작업 완료 후 콜백 실행')
})
// 출력 결과
// 비동기 작업 완료
// 작업 완료 후 콜백 실행
➤ 이로 인해 "콜백 지옥" 발생 😱
➤ Promise 기반의 HTTP 클라이언트 라이브러리가 바로 Axios
// 비동기 콜백 방식
work1(function () {
// 첫번째 작업 ...
work2(result1, function (result2) {
// 두번째 작업 ...
work3(result2, function (result3) {
console.log('최종 결과 :' + result3)
})
})
})
then 메서드를 통해 여러 비동기 작업을 연결하는 체이닝(Chaining) 하여 순차적으로 연결// promise 방식
work1()
.then((result1) => {
// work2
return result2
})
.then((result2) => {
// work3
return result3
})
.catch((error) => {
// error handling
})
then과 catch는 모두 항상 promise 객체를 반환➤ 계속해서 chaining을 할 수 있음
then을 계속 이어 나가면서 작성할 수 있게 됨💡 chaining: 함수 반환 값에 꼬리를 물고 다음 함수를 바로 호출하는 것
axios({}).then(...).then(...).catch(...)
axios({}) // Promise 객체 return
.then(성공하면 수행할 1번 콜백함수)
.then(1번 콜백함수가 성공하면 수행할 2번 콜백함수)
.then(2번 콜백함수가 성공하면 수행할 3번 콜백함수)
...
.catch(실패하면 수행할 콜백함수)
chaining을 활용해 cat api 실습 코드 개선하기
➤ 첫번째 then 콜백함수의 반환 값이 이어지는 then 콜백함수의 인자로 전달
.then((response) => {
imgUrl = response.data[0].url
imgElem = document.createElement('img')
imgElem.setAttribute('src', imgUrl)
document.body.appendChild(imgElem)
})
.then((response) => {
imgUrl = response.data[0].url
return imgUrl
})
.then((imgData) => {
imgElem = document.createElement('img')
imgElem.setAttribute('src', imgData)
document.body.appendChild(imgElem)
})
| 개념 | 설명 |
|---|---|
| 동기 | 순차적 처리, 앞 작업이 끝나야 다음 작업 실행 |
| 비동기 | 병렬 처리, 작업 완료를 기다리지 않고 다음 작업 실행 |
| Ajax | 비동기 웹 통신 기술의 집합 (개념) |
| Axios | Promise 기반 HTTP 클라이언트 라이브러리 (도구) |
| Callback | 비동기 작업 완료 후 실행할 함수 (콜백 지옥 발생) |
| Promise | 비동기 작업의 최종 결과를 나타내는 객체 (체이닝으로 해결) |
| then | 성공 시 실행할 콜백 지정 |
| catch | 실패 시 실행할 콜백 지정 |