2017-01-04 2 views
0

Это работает, но я немного нервничаю по этому поводу, так как не уверен, что это просто взломать или переделать. Может кто-то, пожалуйста, дайте мне знать, если это взломать или переделать?Typcript - вызывает другой метод внутри .subscribe() хорошей или плохой практики?

Я сделал это таким образом, чтобы первый метод выполнялся полностью, прежде чем начинать второй метод.

Если это плохая практика, я уверен, что это лучший способ ее реализовать.

У меня есть один метод, который делает вызов метода HTTP GET, а затем в подписке связывает его и вызывает другой метод, который вызывает другую услугу с использованием этих данных.

private bind(): void { 

     this.Service.get(this.Id) 
     .catch(this.logger.log) 
     .subscribe(
     (customers: PersonalInfo[]) => { 

     this.customers = customers;    
       this.bindContactInfo();   
     } 
     ); 
    } 

private bindContactInfo():void{  

     this.Service.getContactInfo(this.Id) 
     .catch(this.logger.log) 
     .subscribe( 

     (contactInfo: ContactInformation[]) => { 

     // stuff in here 
     } 
     ); 
     } 
+2

Могут быть случаи, когда другие методы могут быть лучше (например, с использованием 'mergeMap'), но нет ничего плохого в вызове другого метода из' callcribe() 'callbacks. –

+1

Я делаю это так, как вы делаете (почти). Возможно, я немного структурирую методы. Если у меня есть два отдельных HTTP-вызова, но нужно сначала получить информацию, я делаю это так, как вы делаете. Если методы не зависят друг от друга, но у меня есть третий метод, который я хочу вызвать после загрузки данных, я обычно делаю 'forkJoin', а затем вызываю третий метод. – John

ответ

3

В общем, вы можете сделать это, я думаю, что в службе это нормально, чтобы сделать это, как это, однако, если ваш код от компонента и так как вы просите «хорошую практику», здесь некоторые варианты:

Вариант 1

Вы должны стараться избегать подписки вручную, используйте .do(...) для тех видов деятельности. Также старайтесь избегать «жесткой цепочки», когда вы не можете использовать детали отдельно, поэтому попробуйте разбить свои потоки на более мелкие, это упростит тестирование. С тех точек, в виду я хотел бы написать свои части, как это:

private getPersonalInfo(): Observable<PersonalInfo[]> { 
    return this.Service.get(this.Id) 
     .catch(this.logger.log) 
     .do((customers: PersonalInfo[]) => this.customers = customers); 
} 

private getContactInfo(): Observable<ContactInformation[]> { 
    return this.Service.getContactInfo(this.Id) 
     .catch(this.logger.log) 
     .do((contactInfo: ContactInformation[]) => this.contactInfo = contactInfo); 
} 

private getData(): void { 
    this.getPersonalInfo() 
     .switchMap(() => this.getContactInfo()) 
     .subscribe(); 
} 

Вариант 2

Поскольку я предполагаю, что вы используете это в качестве компонента, я бы попытаться избежать вещей например, this.contactInfo = contactInfo и попробуйте использовать | async в шаблоне (учитывая, что я использую компоненты только для отображения информации и не выполняю там никаких расчетов)

id$: ReplaySubject<string> = new ReplaySubject<string>(1); // this comes possibly from a service or from an @Input 

personalInfo$: Observable<PersonalInfo[]> = this.id$ 
     .switchMap(id => this.Service.get(id)) 
     .catch(this.logger.log) 
     .publishReplay(1) 
     .refCount(); 

contactInfo$: Observable<ContactInformation[]> = this.id$ // or start it with this.personalInfo$.switchMapTo(this.id$) if you want to make sure that it is executed AFTER the personalInfo was fetched 
     .switchMap(id => this.Service.get(id)) 
     .getContactInfo(this.Id) 
     .catch(this.logger.log) 
     .publishReplay(1) 
     .refCount(); 

и в шаблоне вы будете использовать его как это:

<div *ngFor="let personalInfo of personalInfo$ | async"> 
    ... 
</div> 

Вариант 3

Используйте некоторые магазин-концепция как ngrx - что, вероятно, вызовет немало реорганизаций.

Смежные вопросы