예시
두 가지 방식을 통해 어떤 비동기 코드가 더 효율적인지, 그리고 각자 어떤 결과를 보여주는지 비교해보자.
[방식 1]: 비동기 안에서 for문 사용하기
async function printEmployees() {
for (let i=1; i<11; i++) {
const response = await fetch(`https://url.com/api/${i}`);
const data = await response.json();
console.log(data);
}
}
printEmployees();
[결과]
{
id: 1,
name: 'name1'
},
{
id: 2,
name: 'name2'
},
...
{
id: 10,
name: 'name10'
}
이 방식은 데이터를 순서대로 가져오고, 10개의 데이터를 가져오는데 약 2초가 걸린다.
[방식 2]: 비동기 밖에서 for문 사용하기
async function printEmployee(id) {
const response = await fetch(`https://url.com/api/${id}`);
const data = await response.json();
console.log(data);
}
for (let i=1; i<11; i++) {
printEmployee(i);
}
[결과]
{
id: 3,
name: 'name3'
},
{
id: 1,
name: 'name1'
},
...
{
id: 7,
name: 'name7'
}
이 방식은 데이터를 순서대로 가져오지 않고, 10개의 데이터를 가져오는데 약 0.5초가 걸린다.
해설
[방식1]은 보다시피 비효율적이다. 데이터를 순서대로 가져오긴 하지만, 시간이 [방식2]의 4배나 더 걸린다.
[방식1]의 for문은 사실 이렇게 작동하고 있다.
async function printEmployees() {
const response = await fetch(`https://url.com/api/${1}`);
const data = await response.json();
console.log(data);
const response = await fetch(`https://url.com/api/${2}`);
const data = await response.json();
console.log(data);
const response = await fetch(`https://url.com/api/${3}`);
const data = await response.json();
console.log(data);
const response = await fetch(`https://url.com/api/${4}`);
const data = await response.json();
console.log(data);
...
}
printEmployees();
- 첫번째 await문을 기다리는 동안 함수 밖으로 나감
- 다시 돌아와서 두 번째 await문을 기다리는 동안 함수 밖으로 나감
- 또 돌아와서 data를 출력한 다음에
- 세번째 await문을 기다리는 동안 함수 밖으로 나감
- 다시 돌아와서 네번째 await문을 기다리는 동안 함수 밖으로 나감
- 또 돌아와서 data를 출력한 다음에
- 다섯번째 await문을...
이런 식으로 열번째까지 진행하기 때문에, 반복문을 돌 때마다 지연 시간이 발생해서 오래 걸리는 것이다.
그럼 [방식2]는 어떻게 작동했을까?
async function printEmployee(id) {
const response = await fetch(`https://url.com/api/${id}`);
const data = await response.json();
console.log(data);
}
printEmployee(1);
printEmployee(2);
...
printEmployee(10);
- 가장 먼저 printEmployee(1) 실행
- 함수 안에서 fetch 리퀘스트를 보내고 기다리는 동안 밖으로 나옴
- printEmployee(2) 실행
- 함수 안에서 fetch 리퀘스트를 보내고 기다리는 동안 밖으로 나옴
- printEmployee(3) 실행...
이런식으로 대기를 걸어놓고 나오는 식인데, 먼저 처리되는 대로 출력되기 때문에 순서는 뒤죽박죽이다. 하지만 그렇기 때문에 지연 시간이 발생하지 않아 빠르다.
이 방식의 중요한 점은 '리퀘스트의 결과를 기다리지 않고 바로 다음 url에 리퀘스트를 보낸다는 것'이다.
쉽게 말해 10개의 리퀘스트를 동시에 보내는 것이다.
그래서 리스폰스도 거의 동시에 돌아오고, 결국 하나의 리퀘스트를 처리하는 시간만큼만 기다리면 되는 것이다.
하지만 이때 리퀘스트를 보낸 순서대로 리스폰스가 돌아온다는 보장은 없다. (순서 뒤죽박죽)
그러나 우리에겐 sort()가 있으므로...
결론
[방식2]를 사용하여 효율적인 비동기 코드를 작성하자.
그리고, [방식2]에서 비동기 실행 결과로 console.log가 아닌 return으로 data를 반환할 때는 어떻게 결과값들을 받으면 좋을지도 알아보자.
'JS' 카테고리의 다른 글
| 자주 사용되는 JavaScript Web API들 (0) | 2025.05.10 |
|---|---|
| Promise.all() 사용하기 (0) | 2025.04.25 |
| default export vs named export (0) | 2025.04.22 |
| some()과 every() (0) | 2025.04.22 |
| 이벤트 객체는 아무데서나 쓸 수 있는게 아니다 (0) | 2025.04.18 |