자바스크립트 비동기 처리란?
특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 자바스크립트의 특성
필요한 이유?
서버로 데이터를 요청했을 때 언제 줄지 모르는 응답을 마냥 기다릴 수 없기 때문!
비동기 처리의 사례1
제이쿼리의 ajax
function getData() {
var tableData;
$.get('https://domain.com/products/1', function(response) {
tableData = response;
});
return tableData;
}
console.log(getData()); // undefined
http get 요청으로 정보를 요청해 받아온 데이터가 response에 담겨 tableData라는 변수에 저장.
데이터가 올 때까지 기다리지 않고 return tableData를 실행하기 때문에 undefined가 출력되는 것.
비동기 처리의 사례2
setTimeout() : Web API의 한 종류
// #1
console.log('Hello');
// #2
setTimeout(function() {
console.log('Bye');
}, 3000);
// #3
console.log('Hello Again');
#1 Hello 출력 → #2 실행 → #3 Hello Again 출력 → (#2 실행 3초 뒤) Bye 출력
비동기 처리 해결하기1
callback
데이터가 준비된 시점에만 동작을 수행하는 셈
function getData(callbackFunc) {
$.get('https://domain.com/products/1', function(response) {
callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
});
}
getData(function(tableData) {
console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});
but, 콜백 함수를 연속해서 사용할 때
콜백 안에 콜백을 계속 무는 형식인 콜백 지옥(Callback hell)이 발생할 수 있다.
가독성이 떨어지고 로직을 변경하기 어려움
콜백 지옥 해결을 위해 아래와 같이 각 콜백 함수를 분리해주는 방법이 있다
function parseValueDone(id) {
auth(id, authDone);
}
function authDone(result) {
display(result, displayDone);
}
function displayDone(text) {
console.log(text);
}
$.get('url', function(response) {
parseValue(response, parseValueDone);
});
비동기 처리 해결하기2
promise
위의 콜백 함수에 프로미스를 적용하면 아래와 같다
function getData(callback) {
// new Promise() 추가
return new Promise(function(resolve, reject) {
$.get('url 주소/products/1', function(response) {
// 데이터를 받으면 resolve() 호출
resolve(response);
});
});
}
// getData()의 실행이 끝나면 호출되는 then()
getData().then(function(tableData) {
// resolve()의 결과 값이 여기로 전달됨
console.log(tableData); // $.get()의 reponse 값이 tableData에 전달됨
});
new Promise()
프로미스 생성. 콜백 함수의 인자는 resolve, reject
프로미스의 3가지 상태(states)
→ Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
→ Fulfilled(이행=완료) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
→ Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태
Fulfilled(이행) 상태
콜백 함수의 resolve 인자를 실행하면 then()을 이용하여 결과값을 받을 수 있다
then()으로 여러 개의 프로미스를 연결할 수 있다
function getData() {
return new Promise(function(resolve, reject) {
var data = 100;
resolve(data);
});
}
// resolve()의 결과 값 data를 resolvedData로 받음
getData().then(function(resolvedData) {
console.log(resolvedData); // 100
});
Rejected(실패) 상태
콜백 함수의 reject 인자를 호출하면 실패 상태가 되어
catch()를 통해 실패한 이유(실패 처리의 결과값)를 받을 수 있다
function getData() {
return new Promise(function(resolve, reject) {
reject(new Error("Request is failed"));
});
}
// reject()의 결과 값 Error를 err에 받음
getData().then().catch(function(err) {
console.log(err); // Error: Request is failed
});
비동기 처리 해결하기3
promise + generator
비동기 처리 해결하기4
async & await
async function logName() {
var user = await fetchUser('domain.com/users/1');
if (user.id === 1) {
console.log(user.name);
}
}
서버에서 사용자 데이터를 불러와서 변수에 담고, 사용자 아이디가 1이면 사용자 이름을 출력.
기본 문법
→ 함수의 앞에 async라는 예약어를 붙인다
→ 비동기 처리 메서드 앞에 await를 붙인다
→ 프로미스 객체를 반환해야 await가 동작한다
→ await의 대상이 되는 비동기 처리 코드는 Axios 등 프로미스를 반환하는 API 호출 함수이다
async function 함수명() {
await 비동기_처리_메서드_명();
}
예외 처리
async function 함수명() {
try {
} catch (error) {
}
}
참고
'Javascript' 카테고리의 다른 글
페이지네이션 javascript (2) | 2023.05.15 |
---|---|
Javascript의 비교 연산자 (2) | 2023.05.01 |
innerHTML innerText textContent 차이점 (1) | 2023.05.01 |
문자열 자르기 substr() (1) | 2023.04.28 |
Uncaught (in promise) TypeError: response.json is not a function (2) | 2023.04.28 |