asinc/await는 JavaScript에서 비동기 작업을 처리하는 문법적 꾀임이며, Promise를 기반으로 하여 비동기 코드를 동기 코드와 유사하게 보이게끔 하여 가독성과 유지보수성을 향상시킵니다.
1. 기본慨念
asinc 키워드:
- 비동기 함수를 정의합니다. 비동기 함수는 항상
Promise 객체를 반환합니다.
- 문법:
async function myFunction() {
// 함수 본문
}
- 특징:
- 함수 내에서 명시적으로
Promise를 반환하지 않더라도, asinc 함수는 결과를 Promise로 자동 포장합니다.
- 함수가 일반 값읠 반환하면, 그 값은 자동으로
resolved된 Promise로 변환됩니다.
await 키워드:
- 비동기 함수의 실행을 일시 중단시켜
Promise가 완료될 때까지 기다리고, 그 결과를 반환합니다.
- 문법:
const result = await somePromise;
- 특징:
await은 코드의 실행을 중단시켜 Promise가 완료될 때까지 기다립니다.
Promise가 rejected되면, 에러가 발생하며 try...catch로 잡을 수 있습니다.
2. 사용 예제
1. 기본 사용법
async function getData() {
return "Hello, asinc/await!";
}
getData().then(console.log); // 출력: Hello, asinc/await!
2. await과 함께 사용
async function getData() {
const result = await new Promise((resolve) => setTimeout(() => resolve("데이터 가져오기 성공"), 1000));
console.log(result); // 출력: 데이터 가져오기 성공
}
getData();
3. 오류 처리
async function getData() {
try {
const result = await new Promise((_, reject) => setTimeout(() => reject("오류가 발생했습니다"), 1000));
console.log(result);
} catch (error) {
console.error(error); // 출력: 오류가 발생했습니다
}
}
getData();
3. asinc/await과 Promise의 비교
1. 코드 가독성
function getData() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve("데이터 가져오기 성공"), 1000);
});
}
getData()
.then((data) => {
console.log(data);
return "다음 단계";
})
.then((nextStep) => {
console.log(nextStep);
})
.catch((error) => {
console.error(error);
});
async function getData() {
try {
const data = await new Promise((resolve) => setTimeout(() => resolve("데이터 가져오기 성공"), 1000));
console.log(data);
const nextStep = "다음 단계";
console.log(nextStep);
} catch (error) {
console.error(error);
}
}
getData();
- 비교:
asinc/await는 중첩된 .then() 체인을 피하고, 동기 코드와 유사한 방식으로 작성할 수 있습니다.
2. 오류 처리
Promise: .catch()를 사용하여 오류를 처리합니다.
asinc/await: try...catch를 사용하여 오류를 처리할 수 있습니다.
4. 주의사항
await는 asinc 함수 내에서만 사용할 수 있습니다:
- 일반 함수 내에서
await를 사용하면 문법 오류가 발생합니다.
await는 현재 비동기 함수의 실행을 중단시킵니다:
await 다음은 Promise를 반환하는 표현식일 수 있습니다:
- 예:
fetch, setTimeout으로 감싼 Promise, 제삼자 라이브러리의 비동기 메서드 등.
- 반환 값은 항상
Promise입니다:
asinc 함수가 일반 값을 반환하더라도, 그 값은 resolved된 Promise로 포장됩니다.
5. 고급 사용법
1. 병렬 실행
async function getData() {
const [data1, data2] = await Promise.all([
new Promise((resolve) => setTimeout(() => resolve("데이터 1"), 1000)),
new Promise((resolve) => setTimeout(() => resolve("데이터 2"), 500)),
]);
console.log(data1, data2); // 출력: 데이터 1 데이터 2
}
getData();
2. 순차 실행
async function getData() {
const data1 = await new Promise((resolve) => setTimeout(() => resolve("데이터 1"), 1000));
console.log(data1);
const data2 = await new Promise((resolve) => setTimeout(() => resolve("데이터 2"), 500));
console.log(data2);
}
getData();
3. 사용자 정의 반환 값
async function getData() {
return { message: "Hello, world!", status: 200 };
}
getData().then((result) => console.log(result)); // 출력: { message: "Hello, world!", status: 200 }
6. 요약
- 장점:
- 코드가 더 간결하고 가독성이 좋습니다.
- 오류 처리가 더 직관적입니다.
- 인간의 동기적 사고 과정에 더 잘 부합합니다.
- 단점:
await을濫用하면 성능 문제 발생할 수 있습니다.
- 오류를 처리하기 위해
try...catch나 .catch()가 필요합니다.
- 적용場面:
- 복잡한
Promise 체인 대신 사용.
- 여러 비동기 작업을 처리할 때
Promise.all이나 Promise.race와 함께 사용.
7. 자주하는 질문
await은 스레드를 차단합니까?
- 아니요.
await은 현재 비동기 함수의 실행만 중단시킵니다.
asinc 함수는 무엇을 반환합니까?
- 여러개의 비동기 작업의 오류를 어떻게 처리합니까?
try...catch로 개별적인 await 오류를 잡거나, Promise.allSettled로 여러 Promise의 결과를 처리할 수 있습니다.