IT관련/Angular

💡 Angular에서 await이 작동하지 않는(것처럼 보이는) 이유

파란하늘999 2026. 3. 17. 07:36

1. Observable을 그대로 방치했을 때

Angular의 HttpClient는 Promise가 아닌 Observable을 반환합니다. await은 오직 Promise가 완료될 때까지 기다립니다. Observable 객체 자체에 await을 걸면, 기다리지 않고 즉시 객체 자체를 반환하며 다음 코드로 넘어가 버립니다.

  • 해결책: lastValueFrom 또는 firstValueFrom을 사용하여 Observable을 Promise로 변환해야 합니다.
// ❌ 잘못된 예시: 기다리지 않음
const data = await this.http.get(url); 

// ✅ 올바른 예시
import { lastValueFrom } from 'rxjs';
const data = await lastValueFrom(this.http.get(url));

2. forEach 루프 안에서 await을 사용할 때

배열을 순회하며 비동기 처리를 할 때 가장 많이 하는 실수입니다. Array.prototype.forEach는 콜백 함수가 비동기(async)여도 그 완료를 기다려주지 않습니다.

  • 해결책: for...of 루프를 사용하거나 Promise.all()을 활용하세요.
// ❌ 루프가 끝나기 전에 아래 코드가 실행됨
items.forEach(async (item) => {
  await this.service.update(item);
});

// ✅ 순차적으로 기다림
for (const item of items) {
  await this.service.update(item);
}

3. Lifecycle Hook과의 비동기 타이밍 이슈

ngOnInit이나 ngOnChanges 같은 생명주기 메서드에 async를 붙일 수는 있지만, Angular 프레임워크 자체가 이 Hook들이 끝날 때까지 렌더링을 멈추고 기다려주지는 않습니다.

  • 현상: 데이터가 다 오지 않았는데 템플릿(HTML)이 먼저 그려져서 undefined 에러가 발생함.
  • 해결책: *ngIf나 Optional Chaining(?.), 또는 Resolver를 사용하여 데이터가 로드된 후 화면이 보이도록 제어해야 합니다.

4. Zone.js와 Change Detection의 오해

await 이후에 값이 바뀌었는데 화면에 반영되지 않는다면, 이는 await이 작동하지 않은 게 아니라 **Change Detection(변화 감지)**이 제때 일어나지 않은 것입니다. 외부 라이브러리나 특정 비동기 상황에서 Zone 밖으로 벗어나면 이런 일이 발생합니다.

  • 해결책: ChangeDetectorRef.detectChanges()를 강제로 호출하거나, 가급적 RxJS의 async 파이프를 활용하세요.

🛠 요약표

원인 해결 방법
Observable 사용 lastValueFrom()으로 변환 후 await
forEach 루프 for...of 또는 Promise.all() 사용
Lifecycle Hook *ngIf나 Resolver로 데이터 바인딩 제어
변화 감지 누락 ChangeDetectorRef 사용 또는 RxJS 패턴 권장
반응형