Лучший способ написать блок if..else в typescript с промежуточным сетевым вызовом

#javascript #typescript #if-statement

#javascript #typescript #if-statement

Вопрос:

Я обнаружил, что пишу много такого кода;

 if(cond){
   /*do some network call */
   this.networkService.invoke(params).subscribe((res) => {
      this.doSomething();
   })
}else{
   /* do something without calling the network */
   this.doSomething();
}
  

По сути, this.doSomething(); он должен вызываться независимо от того, выполнено условие или нет. Если cond === true , то выполните какой-нибудь сетевой вызов, затем this.doSomething() . Есть ли лучший способ написать такой код?

Комментарии:

1. Я предполагаю, что это наблюдаемое, и у меня действительно нет опыта работы с ними, но с обещанием шаблон будет выглядеть примерно так : const p = cond ? this.nS.invoke() : Promise.resolve(); p.then(() => this.doSomething()); . Другими словами, создайте обещание в любом случае, а затем разрешите doSomething асинхронно в любом случае.

Ответ №1:

Преобразовав ваш observable в promise и сделав родительскую функцию асинхронной, вы можете сделать это:

 async parentFunction() {
    ...
    cond amp;amp; await this.networkService.invoke(params).toPromise()
    this.doSomething();
}  

Комментарии:

1. Это в значительной степени ответ, но я бы рекомендовал просто использовать if оператор, а не злоупотреблять amp;amp; странностями.

2. @H.B. Да, я согласен. использование if инструкции делает код более читаемым и простым.

Ответ №2:

Возможно, это не то, о чем вы спрашиваете, но большую часть времени (ИМХО) проблема с этим типом кода заключается в том, что он иногда синхронный, а иногда асинхронный. Чтобы избежать этого, вы можете использовать rxjs оператор of , чтобы всегда использовать асинхронный способ.

Недавно я сделал нечто подобное со службой кэша. Идея здесь в том, чтобы всегда возвращать Observable , даже если данные уже загружены;

 private data: SomeData[] = null;
private isLoadedOrOnItsWay = false;
private subject: Subject<SomeData[]> = new Subject<SomeData[]>();

constructor(private dataService: DataService) { }

public getAll(): Observable<SomeData[]> {
    if (!this.isLoadedOrOnItsWay) {
        this.isLoadedOrOnItsWay = true;
        this.dataService.getData<SomeData[]>().subscribe(x => {
            // Load from service...
            this.data = x;
            this.subject.next(x);
        });
    } else if (this.data) {
        // Get from cache
        return of(this.data);
    }

    // Return subject and wait for data to be loaded
    return this.subject;
}