안녕하세요! 오늘은 for...of
와 for await...of
의 차이점에 대해 알아보려고 합니다. 이 두 구문의 차이를 정확히 아는 개발자가 생각보다 적은데요, 실제 프로젝트에서 잘못 사용하면 심각한 버그를 유발할 수 있습니다. 차근차근 알아보도록 할게요!
1. 기본 개념
for...of
for (const item of items) {
// items는 일반 배열
console.log(item);
}
- 일반 배열을 순회할 때 사용
- Symbol.iterator를 구현한 모든 컬렉션에 사용 가능
- 배열, 문자열, Map, Set 등에 사용
for await...of
for await (const item of items) {
// items는 Promise 배열 또는 AsyncIterable
console.log(item);
}
- Promise 배열이나 AsyncIterable을 순회할 때 사용
- 각 요소가 resolve될 때까지 기다림
- async 함수 내에서만 사용 가능
2. 실제 사용 예시
2.1 일반 배열 순회
const fruits = ['apple', 'banana', 'orange'];
// ✅ 올바른 사용
for (const fruit of fruits) {
console.log(fruit);
}
// ❌ 불필요한 사용 (일반 배열에는 for await...of가 필요없음)
for await (const fruit of fruits) {
console.log(fruit);
}
2.2 Promise 배열 순회
const promises = [
Promise.resolve('data1'),
Promise.resolve('data2'),
Promise.resolve('data3')
];
// ✅ 올바른 사용
for await (const result of promises) {
console.log(result); // 'data1', 'data2', 'data3'
}
2.3 비동기 작업이 포함된 일반 배열 순회
// 데이터베이스 작업 예시
const users = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
{ id: 3, name: 'Bob' }
];
// ✅ 올바른 사용
for (const user of users) {
await db.save(user); // 각 작업마다 개별적으로 await
}
// ❌ 잘못된 사용
for await (const user of users) {
db.save(user); // users가 Promise 배열이 아니므로 부적절
}
3. 실제 프로젝트 사례
제가 최근에 경험한 실제 프로젝트 사례를 공유해드릴게요.
// 테스트 데이터 설정
const TEST_DATA = {
users: [
{
data: { nickname: 'user1' },
profile: { email: 'user1@test.com' }
},
{
data: { nickname: 'user2' },
profile: { email: 'user2@test.com' }
}
]
};
// ✅ 올바른 구현
async function setupTestData() {
for (const user of TEST_DATA.users) {
await userRepository.insert(user.data);
await profileRepository.insert(user.profile);
}
}
// ❌ 잘못된 구현
async function setupTestData() {
for await (const user of TEST_DATA.users) { // TEST_DATA.users는 일반 배열
userRepository.insert(user.data); // await 없음
profileRepository.insert(user.profile); // await 없음
}
}
이 경우 잘못된 구현에서는 두 가지 문제가 발생합니다:
TEST_DATA.users
는 Promise 배열이 아닌데for await...of
를 사용- 데이터베이스 작업에
await
가 없어 순서가 보장되지 않음
4. 결론
언제 for...of를 사용하나요?
- 일반 배열을 순회할 때
- 배열 내 각 요소에 대해 비동기 작업이 필요할 경우 개별 await 사용
언제 for await...of를 사용하나요?
- Promise 배열을 순회할 때
- AsyncIterable 객체를 순회할 때
- Stream 데이터를 처리할 때
핵심 포인트
- 순회하는 대상이 무엇인지 정확히 파악하기
- Promise 배열이 아니라면 for...of 사용
- 비동기 작업은 항상 await 잊지 않기
이렇게 사용하시면 실수를 줄일 수 있을 거예요! 혹시 추가 질문이나 궁금한 점이 있다면 댓글로 남겨주세요. 😊
참고자료
'개발 > NestJS' 카테고리의 다른 글
[NestJS] interface, type, class 도입기 (언제 뭘쓰지??) (2) | 2025.01.22 |
---|---|
[NestJS] Queue 완벽 가이드: 기초 개념부터 실전 활용까지 (0) | 2024.11.25 |
NestJS JWT 인증 시 발생하는 'secretOrPrivateKey must have value' 에러 완벽 해결하기 🔐 (1) | 2024.11.21 |
TypeORM에서 insert() 사용 시 @BeforeInsert가 동작하지 않는 문제 해결하기 🤔 (0) | 2024.11.20 |
NestJS 설정 관리의 진화: nestjs-library-config 도입기 (4) | 2024.11.18 |
댓글