inflearn logo
강의

Course

Instructor

TypeScript Introduction - From Basics to Practice

Defining and practicing the main method (query) type

생성자에서 비동기처리

1172

iksukis8604

1 asked

1

안녕하세요 캡틴판교님, 강의 잘 듣고있습니다.

실습에서 구현한 클래스를 보면 생성자에서 비동기처리를 수행하는 함수가 실행되고(fetchData())있는데요, 

다음과같이 만들고 메소드를 실행했을 때 비동기처리때문인지 결과 값이 빈 배열이 나오는 것을 볼 수 있었습니다...

 

그래서 질문은

  1. 해당 실습코드처럼 클래스의 생성자에서 비동기처리를 하는 함수를 실행하는 방식을 많이 이용하나요? 뭔가 제 생각으로는 생성자에서 비동기로 데이터를 받아와 멤버변수에 값을 넣는 경우 멤버함수(메소드)를 외부에서 이용할 경우 위처럼 문제가 생길 것 같아서요.
  2. 실습에서 구현한 클래스를 어떻게 잘 사용할 수 있을까요? 제가 이해한 실습코드의 클래스 로직은 이렇습니다. 
    1. 클래스가 만들어지고(new AddressBook()) 클래스 생성자에서 fetchData() - fetchContracts()실행 -> 비동기로 처리됨
    2. 1이 처리되어 멤버변수 contracts에 받아온 데이터가 할당되기 전 외부의 코드 실행됨(위 스샷)
    3. 1이 처리되기 전에 실행되었기 때문에 빈배열 출력

--클래스의 메소드를 사용하고 싶은 경우 생성자가 실행된 이후 메소드들을 실행할 수 있도록 async-await나 프로미스를 이용해 처리를 해줘야 할 것으로 생각되는데, 어떻게 구현할 수 있을지 감이 오지 않습니다... 도와주실 수 있으실까요?

 

 

 

javascript es6 typescript

Answer 3

1

gimmicks

답변 감사합니다! 

0

haguri

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

captain

안녕하세요 좋은 질문이네요. 보통 클래스 생성을 비동기로 처리하지는 않기 때문에 클래스를 생성하고 나서 비동기 처리가 필요한 로직은 async, 프로미스 등을 붙여 명시적으로 비동기 처리를 해줍니다. 질문하신 내용들은 클래스 설계를 어떻게 하느냐에 따라서 답이 달라질 것 같아요. 보통 클래스를 모델 레이어로 설계하거나 MVC 모델의 Controller로 설계하거나 목적에 따라 다르게 설계합니다.

마찬가지로 제가 설계한 클래스는 학습 목적으로 설계된 구조이지 실제 애플리케이션에서 저렇게 꼭 써야합니다 라고 설계한 건 아닙니다. 더불어서 제가 만약 저 클래스를 실제 DOM 조작과 연계한 코드로 활용한다고 한다면 클래스를 생성하고 바로 어떤 메서드를 호출하는 것이 아니라 화면에 렌더링 될 때 이미 데이터를 다 들고와 있도록 클래스를 생성해 두었을 것 같아요.

질문하신 내용이 단편적으로 답변하기가 어려워서 답변이 길어졌네요. 보시고 또 궁금하신거 있으면 알려주세요 :)

TSLint

0

66

1

vscode eslint server 오류

0

75

1

안녕하세요. 기본타입- 튜플, 객체, 진위값 부분의 영상의 화면이 나오질 않습니다.

0

77

1

live server 설치 오류

1

370

2

강의 교안 pdf 는 따로 제공하지않나요?

0

284

2

npm i 설치 이유 문의

1

404

3

index.ts Delete &#x60;␍&#x60;eslintprettier/prettier 오류(빨간줄) 해결

2

289

3

vue 에서 jquery 사용 문제

1

692

2

TSLint 확장 프로그램은 현재 지원하지 않는다고 합니다.

1

499

2

강의 내용처럼 노란 밑줄이 작동하지 않아서 유사 질문들을 실행해보았는데요

1

542

1

section 3-1 JSdoc 타입이 추론되지 않아서 다음과 같이 수정했는데 이거 맞나요?

1

452

2

함수에 리턴 안됐다고 노란밑줄이 쳐져야하는데 없습니다

2

455

1

파일이 다른데 식별자가 중복되었다고 뜹니다.

1

443

2

빨간줄 에러 질문드립니다

1

489

2

마우스 갖다대면 리턴값 설명 나오는 거 질문드려요

1

356

2

js에서 @ts-check 적어도 체크하지 못하는 문제입니다

2

393

2

index.html에서 타입스크립트 콘솔 찍는 법 질문드립니다

1

566

2

섹션 1-3 추론 질문드립니다

1

354

2

왜 api쪽에는 왜 에러가 안나는지 궁금합니다.

1

323

2

const item1을 선언했을 때 타입을 선언해줘도 괜찮을까요?

1

391

1

전화번호부 타입선언

1

266

2

타입을 전역으로 분리

1

593

2

객체 선언 시 구분자는 쉼표, 세미콜론 모두 사용가능한건가요?

1

460

1

Git 관련 질문이 있습니다

1

670

2