작성
·
934
1
안녕하세요 캡틴판교님, 강의 잘 듣고있습니다.
실습에서 구현한 클래스를 보면 생성자에서 비동기처리를 수행하는 함수가 실행되고(fetchData())있는데요,
다음과같이 만들고 메소드를 실행했을 때 비동기처리때문인지 결과 값이 빈 배열이 나오는 것을 볼 수 있었습니다...
그래서 질문은
--클래스의 메소드를 사용하고 싶은 경우 생성자가 실행된 이후 메소드들을 실행할 수 있도록 async-await나 프로미스를 이용해 처리를 해줘야 할 것으로 생각되는데, 어떻게 구현할 수 있을지 감이 오지 않습니다... 도와주실 수 있으실까요?
답변 3
1
0
interface PhoneNumberDictionary {
[phone: string]: { num: number };
}
interface Contact {
name: string;
address: string;
phones: PhoneNumberDictionary;
}
enum PhoneType {
Home = 'home',
Office = 'office',
Studio = 'studio',
}
// api
function fetchContacts(): Promise<Array<Contact>> {
const contacts: Array<Contact> = [
{
name: 'Tony',
address: 'Malibu',
phones: {
home: { num: 11122223333 },
office: { num: 44455556666 },
},
},
{
name: 'Banner',
address: 'New York',
phones: {
home: { num: 77788889999 },
},
},
{
name: '마동석',
address: '서울시 강남구',
phones: {
home: { num: 213423452 },
studio: { num: 314882045 },
},
},
];
return new Promise(resolve => {
setTimeout(() => resolve(contacts), 2000);
});
}
// main
class AddressBook {
contacts: Array<Contact>;
constructor() {
this.contacts = [];
// this.fetchData();
}
async fetchData(): Promise<void> {
// fetchContacts().then(res => {
// this.contacts = res;
// });
const res = await fetchContacts();
this.contacts = res;
}
findContactByName(name: string): Array<Contact> {
return this.contacts.filter(contact => contact.name === name);
}
findContactByAddress(address: string): Array<Contact> {
return this.contacts.filter(contact => contact.address === address);
}
findContactByPhone(
phoneNumber: number,
phoneType: PhoneType
): Array<Contact> {
return this.contacts.filter(
contact => contact.phones[phoneType].num === phoneNumber
);
}
addContact(contact: Contact): void {
this.contacts.push(contact);
}
displayListByName(): Array<string> {
return this.contacts.map(contact => contact.name);
}
displayListByAddress(): Array<string> {
return this.contacts.map(contact => contact.address);
}
}
(async (): Promise<AddressBook> => {
console.log('Wait for 2 seconds..');
const addressBook = new AddressBook();
await addressBook.fetchData();
return addressBook;
})().then(addressBook => {
console.log(addressBook);
console.log(addressBook.findContactByName('마동석'));
console.log(addressBook.findContactByAddress('Malibu'));
console.log(addressBook.findContactByPhone(77788889999, PhoneType.Home));
console.log(addressBook.displayListByName());
console.log(addressBook.displayListByAddress());
console.log('=================================================');
addressBook.addContact({
name: 'Haguri',
address: 'Jeonbuk',
phones: {
home: { num: 1011119999 },
office: { num: 6312345678 },
},
});
console.log(addressBook.contacts);
});
위 코드는 제가 작성하고 테스트 해본 코드이구요. 참조 링크는 아래와 같습니다.
https://stackoverflow.com/questions/36363278/can-async-await-be-used-in-constructors
0
안녕하세요 좋은 질문이네요. 보통 클래스 생성을 비동기로 처리하지는 않기 때문에 클래스를 생성하고 나서 비동기 처리가 필요한 로직은 async, 프로미스 등을 붙여 명시적으로 비동기 처리를 해줍니다. 질문하신 내용들은 클래스 설계를 어떻게 하느냐에 따라서 답이 달라질 것 같아요. 보통 클래스를 모델 레이어로 설계하거나 MVC 모델의 Controller로 설계하거나 목적에 따라 다르게 설계합니다.
마찬가지로 제가 설계한 클래스는 학습 목적으로 설계된 구조이지 실제 애플리케이션에서 저렇게 꼭 써야합니다 라고 설계한 건 아닙니다. 더불어서 제가 만약 저 클래스를 실제 DOM 조작과 연계한 코드로 활용한다고 한다면 클래스를 생성하고 바로 어떤 메서드를 호출하는 것이 아니라 화면에 렌더링 될 때 이미 데이터를 다 들고와 있도록 클래스를 생성해 두었을 것 같아요.
질문하신 내용이 단편적으로 답변하기가 어려워서 답변이 길어졌네요. 보시고 또 궁금하신거 있으면 알려주세요 :)