비동기 통신을 비교하기에 앞서 동기와 비동기가 어떤 차이가 있는지 간단하게 알아보자.
동기는 말 그대로 동시에 일어난다는 뜻이다. 요청과 그 결과가 동시에 일어난다는 약속인데 바로 요청을 하면 시간이 얼마가 걸리던지 요청한 자리에서 결과가 주어져야 한다.
비동기는 동시에 일어나지 않는다를 의미하는데 요청과 결과가 동시에 일어나지 않을거라는 약속이다.
동기방식은 설계가 매우 간단하고 직관적이지만 결과가 주어질때까지 아무것도 못하고 대기해야 한다는 단점이 있고, 비동기방식은 복잡하지만 결과가 주어지는데 시간이 걸리더라도 그 시간 동안 다른 작업을 할 수 있으므로 자원을 효율적으로 사용할 수 있다는 장점이 있다.
js는 동기적인 언어이지만, 때로는 비동기적으로 처리한다.
만약 자바스크립트에 많은 양의 데이터를 요청하면, 응답을 받기위해 많이 대기를 해야한다.
이 경우에는 데이터 응답을 받기 전까지 다른 작업을 수행할 수 없는 문제가 발생한다.
이러한 경우에는 자바스크립트는 비동기적으로 작업을 처리한다.
1) promise 란?
2) promise의 3가지 상태
A. 대기 상태
new Promise()
를 이용해 promise 객체를 생성한 시점이다.new Promise();
B. 이행 상태
resolve()
가 실행된 상태로, 이를 이행 상태라고 한다.function printNumber(n) {
return new Promise((resolve, reject) => {
const number = n + 1;
resolve(number); // resolve == 비동기처리 성공!
})
}
resolve()
에 전달한 파라미터는 then()
에서 사용할 수 있다.printNumber(1).then((n) => console.log(n)); // 2
C. 거절 상태
reject()
가 실행된 상태로, 이를 거절 상태라고 한다.catch()
에서 에러원인을 확인할 수 있다.reject()
를 실행했다.function printNumber(n) {
return new Promise((resolve, reject) => {
const number = n + 1;
if (number === 3) {
let error = new Error();
error.name = 'ValueIsThreeError';
return reject(error);
}
resolve(number);
})}
printNumber(2).catch(e => console.error(e)); // error: ValueIsThreeError
3) promise 사용 예시
getApartmentInfo()
를 사용해 아파트 정보를 받고, 결과를 출력하고자 한다.resolve()
에 응답값을 넘기고, 실패했을 시 reject()
에 에러 메시지를 넘겨준다.function getApartmentInfo() {
return new Promise(function(resolve, reject) {
$.get('url주소', (response) => {
if (response) resolve(response); // 성공시 응답값을 넘김
reject(new Error("InValid Request Error")); // 실패시 에러메시지를 넘김
})
})
}
then()
에서 그 응답 결과를 사용할 수 있다.catch()
를 사용하여 에러 메시지를 확인할 수 있다.getApartmentInfo()
.then((data) => { // 성공시 응답값을 출력
console.log(data);
})
.catch((error) => { // 실패시 에러 메시지를 출력
console.error(error);
})
1) async & await 란?
async & await
도 promise
처럼 비동기 처리를 위해 사용된다.promise
를 더 쉽게 사용할 수 있는 방법이다.2) async & await 사용법
async
를 비동기 대상 앞에 await
를 붙여주면 된다.function getData() {
// 서버에서 데이터를 요청하는 함수
}
async function printData() { // 1. 동기적으로 처리할거야
const data = await getData(); // 2. getData 처리를 기다릴거야
console.log(data); // 3. getData처리 성공 후 실행할 코드이지!
})
}
try~catch
문을 사용하면 된다.1) async & await는 간결하다
promise
를 사용한 비동기 처리function printAnimals() {
return getAnimals()
.then(data => {
if (data.property) {
return sampleFunc1(data)
.then(anotherData => {
console.log(anotherData)
})
}else {
console.log(data)
}
})
}
async & await
를 사용한 비동기 처리async function printAnimals() {
const animals = await getAnimals();
if (animals.property) {
const sampleData = await sampleFunc1(animals);
console.log(sampleData);
}else {
console.log(animals);
}
}
2) async & await는 에러 핸들링에 유리하다
printAnimals()
에서 에러가 발생한 게 아니라, JSON.parse
에서 에러가 발생했다고 가정했을 때 then
을 사용하면 내부에 추가적인 catch
문을 적어줘야한다.function printAnimals() {
try {
getAnimals()
.then((response) => {
const data = JSON.parse(response); // 여기서 에러 발생한다고 가정
console.log(data);
})
.catch((err)=> { // 추가적인 에러
console.log(err)
})
}
catch(err) {
console.log(err)
}
}
async & await
를 사용하게 되면 하나의 catch
만 해주면된다.async function printAnimals() {
try {
const data = await JSON.parse((getAnimals())
console.log(data);
}
catch(err) {
console.log(err)
}
}
3) async & await는 에러 위치를 찾기 쉽다
then
에서 에러가 발생했는지 찾기가 어렵다.function sample() {
return sampleFunc()
.then(data => return data)
.then(data2 => return data2)
.then(data3 => return data3)
.catch(err => console.log(err)) // 결과적으로 문제가 발생했다
}
async
를 사용하게 되면, 어떤 지점에서 에러가 발생했는지 쉽게 찾을 수 있다.async function sample() {
const data1 = await sampleFunc(); // 문제 발생시 data1값이 유효치 않음
const data2 = await sampleFunc2(data1);
return data2;
}