fetchURL(url1, function(response1) {
fetchURL(url2, function(response2) {
fetchURL(url3, function(response3) {
//...
console.log(1);
})
console.log(2);
})
console.log(3);
})
console.log(4);
promise
) 개념 도입 const page1Promise = fetch(url1);
page1Promise.then(response1 => {
return fetch(url2);
}).then(response2 => {
return fetch(url3);
}).then(response3 => {
// ...
}).catch(error => {
// ...
})
async
& await
키워드 도입 async function fetchPages() {
const response1 = await fetch(url1);
const response2 = await fetch(url2);
const response3 = await fetch(url3);
}
await
: 각각의 프로미스가 처리(resolve)될 때까지 fetchPages
함수 실행 멈춤 async
함수 내에서 await
중인 프로미스가 거절(reject)되면 예외 던짐try
/catch
구문 사용 가능 async function fetchPages() {
try {
const response1 = await fetch(url1);
const response2 = await fetch(url2);
const response3 = await fetch(url3);
} catch (e) {
// ...
}
}
ES5- 버전 대상으로 할 때의 TS 컴파일러 : async
& await
가 동작하도록 정교한 변환 수행
→ TS는 런타임에 관계 없이 async
& await
사용 가능
콜백보다 프로미스
나 async
/await
를 사용해야 하는 이유
ex) 병렬로 페이지 로드하고 싶다면 Promise.all
사용해 프로미스 조합
async function fetchPages() {
const [response1, response2, response3] = await Promise.all([
fetch(url1), fetch(url2), fetch(url3)
]);
// ...
}
→ best case. await
와 구조 분해 할당
response
변수 각각의 타입을 Response로 추론 function fetchPagesCB() {
let numDone = 0;
const response: string[] = [];
const done = () => {
const [response1, response2, response3] = response;
// ...
};
const urls = [url1, url2, url3];
urls.forEach((url, i) => {
fetchURL(url, r => {
response[i] = url;
numDone++;
if (numDone === urls.length) done();
})
})
}
: 위 코드에 오류 처리 포함 & Promise.all
과 같은 일반적 코드로의 확장은 어려움
Promise.race
도 타입 추론과 잘 맞음Promise.race
사용해 프로미스에 타임아웃을 추가하는 방법도 많이 사용됨 function timeout(millis: number): Promise<never> {
return new Promise((resolve, reject) => {
setTimeout(() => reject('timeout'), millis)
})
}
async function fetchWithTimeout(url: string, ms: number) {
return Promise.race([fetch(url), timeout(ms)])
}
async
/await
를 사용해야 하는 이유 // function getNumber(): Promuse<number>
async function getNumber() {
return 42;
}
// async 화살표 함수
const getNumber = async () => 42; // type : () => Promise<number>
// 프로미스르 직접 생성하는 방법
const getNumber = () => Promise.resolve(42); // type : () => Promise<number>
: 즉시 사용 가능한 값에도 프로미스를 반환하는 것이 이상하게 보일 수 있으나,
비동기 함수로 통일하도록 강제하는 데 도움
→ 함수는 항상 동기 또는 항상 비동기로 실행되어야 하며, 혼용해서는 안됨
async
& await
사용을 권장