동기 (Synchronous)
" 모든 일을 순서대로 하나씩 처리하는 것"
순서대로 처리한다 == 이전 작업이 끝나야 다음 작업 시작
요청과 응답을 동기식으로 처리한다면?
-> 요청을 보내고 응답이 올 때까지 기다렸다가 다음 로직 처리
비동기 (Asynchronous)
" 작업을 시작한 후 결과를 기다리지 않고 다음 작업을 처리하는 것 (병렬적) "
시간이 필요한 작업들은 요청을 보낸 뒤 응답이 빨리 오는 작업부터 처리
ex) 메일 전송 버튼을 눌러 놓고 다른 작업을 수행할 수 있음
비동기를 사용하는 이유 == 사용자 경험
"동기식 처리는 특정 로직이 실행되는 동안 다른 로직 실행을 차단하기 때문에
마치 프로그램이 응답하지 않는 듯한 사용자 경험을 만들게 됨"
=> 비동기로 처리한다면 먼처 처리되는 부분부터 보여줄 수 있으므로, 사용자 경험에 긍정적 효과!
=> 이와 같은 이유로 많은 웹 기능은 비동기 로직으로 구현되어 있음
JavaScript의 비동기 처리
JavaScript는 한 번에 하나의 일만 수행할 수 있는 Single Thread 언어로 동시에 여러 작업을 처리할 수 없음
즉, JavaScript는 하나의 작업을 요청한 순서대로 처리할 수 밖에 없다.
JavaScript 자체는 Single Thread이므로 비동기 처리를 할 수 있도록 도와주는 환경이 필요
JavaScript에서 비동기와 관련한 작업은 브라우저 또는 Node 환경에서 처리
브라우저 환경에서의 비동기 동작을 구성하는 요소
Call Stack | 요청이 들어올 때 마다 순차적으로 처리하는 Stack 기본적인 JavaScript의 Single Thread 작업 처리 |
Web API | JavaScript 엔진이 아닌 브라우저에서 제공하는 Runtime 환경으로 시간이 소요되는 작업을 처리 - setTimeout, DOM Event, AJAX 요청 등 [참고] Runtime : 특정 언어가 동작할 수 있는 환경 |
Task Queue | 비동기 처리된 Callback 함수가 대기하는 Queue |
Event Loop | CallStack 과 Task Queue를 지속적으로 모니터링 -> Call Stack이 비어 있는지 확인 후 비어있다면 대기 중인 오래된 작업을 Call Stack으로 Push |
비동기 처리 동작 방식
1. 모든 작업은 Call Stack으로 들어간 후 처리
2. 오래 걸리는 작업이 Call Stack으로 들어오면 Web API로 보내 별도로 처리
3. Web API 에서 처리가 끝난 작업들은 Call Stack으로 들어가지 못하고 Task Queue에 순서대로 들어감
4. Event Loop가 Call Stack이 비어있는 것을 계속 체크하고 Call Stack이 빈다면 Task Queue에서 가장 오래된 작업을 Call Stack으로 보냄
Axios 라이브러리
: JavaScript의 HTTP 웹 통신을 위한 라이브러리
-> 확장 가능하나 인터페이스와 쉽게 사용할 수 있는 비동기 통신 기능을 제공
[공식 문서]
Axios 사용해보기
axios.get("요청할 URL")
.then(성공 시 수행할 콜백 함수)
.catch(실패 시 수행할 콜백 함수)
-> get, post 등 여러 method 사용가능
-> then을 이용해서 성공하면 수행할 로직을 작성
-> catch를 이용해서 실패하면 수행할 로직을 작성
Axios로 요청해보기
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
// console.log('고양이는 야옹')
const catImageSearchURL = 'https://api.thecatapi.com/v1/images/search'
const btn = document.querySelector('button')
// Promise 객체를 리턴하는 axios 라이브러리
// console.log(axios.get(catImageSearchURL))
btn.addEventListener('click', function () {
// 권장 표기 방식
axios({
method: 'get',
url: catImageSearchURL,
})
.then((response) => {
// console.log(response.data[0].url)
imgElem = document.createElement('img')
return imgElem
})
.then((imgElem) => {
imgElem.setAttribute('src', response.data[0].url)
document.body.appendChild(imgElem)
})
.catch((error) => {
console.log('실패했다옹')
})
console.log('야옹야옹')
// 일반 표기 방식
axios.get(catImageSearchURL)
.then((response) => {
// console.log(response.data[0].url)
imgElem = document.createElement('img')
return imgElem
})
.then((imgElem) => {
imgElem.setAttribute('src', response.data[0].url)
document.body.appendChild(imgElem)
})
.catch((error) => {
console.log('실패했다옹')
})
// console.log('야옹야옹')
})
</script>
Callback 과 Promise
비동기 처리의 핵심은 Web API로 들어오는 순서가 아니라 작업이 완료되는 순서에 따라 처리한다는 것
-> 실행 결과를 예상하면서 코드를 작성할 수 없게 함
" 어떻게 해야할까? 콜백 함수를 사용하자!!"
CallBack Function
: 다른 함수의 인자로 전달되는 함수
- 동기, 비동기 상관없이 사용 가능
- 비동기 작업이 완료된 후 실행할 작업을 명시하는 데 사용되는 콜백 함수를 비동기 콜백 이라함
콜백 함수 예시
// 이벤트 리스너
btn.addEventListener('click', () => {
alert('버튼 클릭!')
})
# Django의 View Function
form django.urls import path
form . import views
urlpatterns = [
path('movies/', views.movies),
]
콜백 함수를 사용하는 이유
-> 명시적인 호출이 아닌 특정한 조건 혹은 행동에 의해 호출되도록 작성할 수 있음
"비동기 처리를 순차적으로 동작할 수 있게 함"
콜백 지옥
: 비동기 처리를 위한 콜백을 작성할 때 마주하는 문제
- 보통 어떤 기능의 실행 결과를 받아서 다른 기능을 수행하기 위해 많이 사용하는데, 이 과정을 작성하다 보면 비슷한 패턴이 계속 발생하게 됨
Promise
: Callback Hell 문제를 해결하기 위해 등장한 비동기 처리를 위한 객체
"작업이 끝나면 실행시켜 주기 약속!"
- 비동기 작업의 완료 또는 실패를 나타내는 객체
Axios 라이브러리는 Promise 기반의 클라이언트!
then(callback) : 성공에 대한 약속
- 요청한 작업이 성공하면 callback 실행
- callback은 이전 작업의 성공 결과를 인자로 전달 받음
catch(callback) : 실패에 대한 약속
- then()이 하나라도 실패하면 callback 실행
- callback은 이전 작업의 실패 객체를 인자로 전달 받음
then & catch
then과 catch 모두 항상 promise 객체를 반환
즉, 계속해서 chaning 할 수 있음 -> then을 계속 이어 나가면서 작성할 수 있었던 것
axios.get('요청할 URL').then(...).then(...).catch(...)
axios.get('요청할 URL')
.then(성공하면 수행할 콜백 함수 1)
.then(1번 콜백함수가 성공하면 수행할 콜백 함수 2)
.then(2번 콜백함수가 성공하면 수행할 콜백 함수 3)
...
.catch(실패하면 수행할 콜백 함수)
work1()
.then((response1) => {
// work2
return response2
})
.then((response2) => {
// work3
return response3
})
.then((error) => {
// 에러 핸들링
})
-> 우리가 일반적으로 위에서 아래로 적는 방식처럼 코드를 작성할 수 있음
promise가 보장하는 것
1. callback 함수는 JavaScript의 Event Loop가 현재 실행 중인 Call Stack을 완료하기 이전에는 절대 호출되지 않음
-> Promise callback 함수는 Event Queue에 배치되는 엄격한 순서로 호출됨
2. 비동기 작업이 성공하거나 실패한 뒤에 .then() 메서드를 이용하여 추가한 경우에도 1번과 똑같이 동작
3. .then()을 여러 번 사용하여 여러 개의 callback 함수를 추가할 수 있음 (Chaning)
-> 각각의 callback은 주어진 순서대로 하나하나 실행하게 됨
-> Chaning은 Promise의 가장 뛰어난 장점
최근엔 너무 아무 생각없이 살아서 걱정될 정도,
'Web > JavaScript' 카테고리의 다른 글
페이지를 떠날 때 안정적으로 요청 보내기 - sendBeacon (1) | 2023.05.21 |
---|---|
[JavaScript] Prototype (0) | 2023.03.06 |
JavaScript 심화 - Event (0) | 2022.10.24 |
JavaScript 심화 - DOM (0) | 2022.10.24 |
JavaScript 기초- Object (0) | 2022.10.19 |
댓글