728x90
const docs = await getDocs(
query(collection(db, "info"), orderBy("date", "desc"))
);
docs.forEach(async (v) => {
const { photo, name, mbti, tmi } = v.data();
// storage에 저장된 사진 파일 가져오기
const forestRef = ref(storage, photo);
const photoPath = await getDownloadURL(forestRef);
const temp_html = `
<div class="col card-list">
<div class="card">
<img id="${v.id}" src="${photoPath}" class="card-img-top ${v.id}" alt="..." />
<div class="card-body main-card">
<div class="card-header">
<div class="header-wrapper">
<h5 class="card-title ${v.id}">${name}</h5>
<p class="card-text ${v.id}">${mbti}</p>
</div>
<button id="${v.id}" class="card-button">삭제</button>
</div>
<div class="card-content">
<span class="${v.id}">${tmi}</span>
</div>
</div>
</div>
</div>`;
$("#card").append(temp_html);
});
상단의 사진과 같이 서버에서 데이터를 가져와서 DOM을 생성하기 위해 forEach와 async-await을 사용했다. 그러나 의도한 바와 다르게 DOM이 일정한 순서없이 제멋대로 생성되었고, DOM 생성 후 등록한 삭제 및 수정 이벤트가 제대로 작동하지 않는 문제가 발생했다.
나는 바로 비동기 처리가 제대로 되지 않아 DOM이 생성되는 순서가 엉망이 되어 발생한 문제라고 생각했고, MDN을 통해 forEach를 자세히 알아봤다. 이에 따르면 forEach는 프로미스를 기다리지 않기 때문에 내가 원했던 바와 같이 날짜 순서대로 데이터를 받아오지 못해 DOM이 순서대로 생성되지 않았던 것이다.
const docs = await getDocs(
query(collection(db, "info"), orderBy("date", "desc"))
);
const data = await Promise.all(
docs.docs.map(async (v) => {
const { photo, name, mbti, tmi } = v.data();
const forestRef = ref(storage, photo);
const photoPath = await getDownloadURL(forestRef);
return { id: v.id, photoPath, name, mbti, tmi };
})
);
// 가져온 데이터로 DOM 생성하기
data.forEach((v) => {
const { id, photoPath, name, mbti, tmi } = v;
const temp_html = `
<div class="col card-list">
<div class="card">
<img id="${id}" src="${photoPath}" class="card-img-top ${v.id}" alt="..." />
<div class="card-body main-card">
<div class="card-header">
<div class="header-wrapper">
<h5 class="card-title ${id}">${name}</h5>
<p class="card-text ${id}">${mbti}</p>
</div>
<button id="${id}" class="card-button">삭제</button>
</div>
<div class="card-content">
<span class="${id}">${tmi}</span>
</div>
</div>
</div>
</div>`;
$("#card").append(temp_html);
});
그래서 Promise.all을 활용해 비동기 처리를 구현하고 Firsebase의 서버에서 받아오는 데이터를 날짜 순으로 data 배열에 저장하였다. 그리고 DOM을 생성하는 로직은 data 배열의 비동기 처리가 완료된 경우 실행되도록 분리했다. 결과적으로 의도한 바와 같이 DOM이 날짜 순으로 제대로 생성되었고, 삭제 및 수정 이벤트도 정상적으로 실행되었다.
Array.prototype.forEach() - JavaScript | MDN
Array 인스턴스의 forEach() 메서드는 각 배열 요소에 대해 제공된 함수를 한 번씩 실행합니다.
developer.mozilla.org
728x90
'자바스크립트' 카테고리의 다른 글
[자바스크립트] 웹팩으로 바닐라js MPA 프로젝트 번들링하기 (1) | 2024.01.12 |
---|---|
[자바스크립트] webpack으로 코드스플리팅 적용하기 (1) | 2024.01.04 |
[자바스크립트] 바닐라 js 프로젝트에 웹팩과 바벨 설정하기 (1) | 2024.01.03 |
[자바스크립트] 실행 컨텍스트와 호이스팅 (0) | 2023.12.29 |