이제 막 슬픔 없이 십오 초 정도가 지났다
팀과제 : Promise.All
문종현
2022. 10. 29. 17:41
몹시 껄끄러워보이는 코드
프로젝트를 하면서 반복문 안에 비동기 함수를 쓸 경우가 생겼다.
findOneOrder = async (orderId) => {
const foundOrder = await this.orderRepository.findOneOrder(orderId);
console.log(foundOrder.get());
const { records } = foundOrder;
console.log("records:", records);
const parsedRecords = JSON.parse(records);
console.log("parsedRecords:", parsedRecords);
const menuList = [];
for (let i = 0; i < parsedRecords.length; i++) {
let menuId = parsedRecords[i].menuId;
let count = parsedRecords[i].count;
if (!menuId || !count) break;
let menu = await this.orderRepository.findOneMenu(menuId);
let Menu = {
menuId: menu.menuId,
name: menu.name,
price: menu.price,
count,
image: menu.image,
};
menuList.push(Menu);
}
const data = {
orderId: foundOrder.orderId,
orderDate: foundOrder.createdAt,
storeId: foundOrder.Store.storeId,
storeName: foundOrder.Store.name,
storePhone: foundOrder.Store.storePhone,
menuList,
};
console.log(data);
return data;
};
물론 작동이야 하지만, 규모가 아주 작은 프로젝트이기 때문이다.
데이터 양이 커지기 시작하면 문제가 될 것을 예상하기란 쉬운 일이다.
편해진 코드
findOneOrder = async (orderId) => {
const foundOrder = await this.orderRepository.findOneOrder(orderId);
console.log(foundOrder.get());
const { records } = foundOrder;
console.log("records:", records);
const parsedRecords = JSON.parse(records);
console.log("parsedRecords:", parsedRecords);
const menuList = [];
const promises = parsedRecords.map(async (record) => {
let menuId = record.menuId;
let count = record.count;
if (menuId && count) {
let menu = await this.orderRepository.findOneMenu(menuId)
let Menu = {
menuId: menu.menuId,
name: menu.name,
price: menu.price,
count,
image: menu.image,
};
return menuList.push(Menu)
}
});
await Promise.all(promises)
console.log("menuList:", menuList);
const data = {
orderId: foundOrder.orderId,
orderDate: foundOrder.createdAt,
storeId: foundOrder.Store.storeId,
storeName: foundOrder.Store.name,
storePhone: foundOrder.Store.storePhone,
menuList,
};
console.log(data);
return data;
};
Promise.All 을 써야겠다는 생각을 품고는 있었지만, 배열 반복문의 경우 어떻게 적용할지 조금의 고민이 있었다.
물론 이런 문제는 대개 샤워를 하거나 하늘을 쳐다보거나 고양이를 구경하다보면 방법이 떠오르기 마련이다.
map 은 비동기마저 콜백으로 잘 받아주고 프로미스 객체들로 이루어진 배열을 반환해준다.
이렇게 기특할 수가 없다.
아직 남은 의문
대체 저 배열 안의 프로미스 객체들은 어떻게 생겼을까.
const menuList = [];
const promises = parsedRecords.map(async (record) => {
let menuId = record.menuId;
let count = record.count;
if (menuId && count) {
let menu = await this.orderRepository.findOneMenu(menuId)
let Menu = {
menuId: menu.menuId,
name: menu.name,
price: menu.price,
count,
image: menu.image,
};
return menuList.push(Menu)
}
});
console.log(promises)
const result = await Promise.all(promises)
console.log(result)
console.log(promises) 의 결과다.
네번째가 undefined인 것은, 들어간 배열 중 앞의 세개만 if문을 통과하기 때문이다.
네번 것은 menuId나 count가 아닌, 다른 정보가 들어간 객체이다.
[
Promise { <pending> },
Promise { <pending> },
Promise { <pending> },
Promise { undefined }
]
console.log(result)의 결과다.
[ 1, 2, 3, undefined ]