Ожидание нескольких наблюдаемых в Angular 5 - PullRequest
0 голосов
/ 13 сентября 2018

Я новичок в Angular и TypeScript, поэтому вопрос может звучать неправильно. Я использую Visual Studio Code и Angular 5 (ng-version = "5.2.11").

Мне нужно «дождаться», пока мой вызов api закончится и вернуть результат, не оборачивая все в гигантский «.subscribe». Что у меня есть:

exampleMethod(): SettingsClass {
const myComplexObject: SettingsClass = {
  field1: predefined.field1,
  field2: predefined.field2,
  field3: isComplexCalculationsNecessary ? this.CallApi_1(predefined.paramForField3) : predefined.field3,
};

return myComplexObject;
}

Раньше у меня были все параметры в " предопределенных ", но теперь мне нужно запросить один (или более) из внешнего источника и немедленно вернуть "myComplexObject" из метода (в какой-то другой вызов API, или другой компонент или даже интерфейс, но мне нужно, чтобы этот объект был полностью определен со всеми параметрами). Я мог бы перевернуть мой код «вверх ногами» и поместить все внутри большого «.subscribe», но я не сделал этого, потому что в какой-то момент мне также понадобится другой параметр для запроса, и все это сломается. Как написать вызов в API, чтобы не переписывать весь мой код каждый раз, когда мне нужно добавить новый внешний вызов? Что-то вроде:

CallApi_1(paramForField3: string): Observable<int> {
return this.http.get(`${httpConfig.route}?$apply=filter${paramForField3}/groupby${httpConfig.groupingParam}`);
}

ИЛИ, может быть

CallApi_1(paramForField3: string): Observable<int> {
return this.ExternalCallsService.GetParam3Information(paramForField3).subscribe(res => 
.GetParam3Information contains the same http call as above, but I need to do
something to return this result outside, I don't know what);
}

Что я ищу, так это какой-то король:

field3: isComplexCalculationsNecessary ? **await** this.CallApi(predefined.paramForField3) : predefined.field3,

В настоящее время я пробую 'rxjs', у которого есть интересные опции для работы с Observables, например 'forkJoin', но я не уверен, что смотрю в правильном направлении полностью, возможно, такой трюк невозможен, или мой понимание Observables не правильно, и мне нужно переместить сложную логику в конец? Пожалуйста, сообщите.

Важно еще раз заметить, что простой ".subscribe" - это не то, что я ищу, потому что во всех примерах подписки мы не возвращаем значения, а присваиваем его какой-то глобальной переменной или непосредственно html-элементу, и это НЕ то, что мне нужно, мне нужно получить значение и продолжать работать с ним так быстро, как внешний ресурс вернет его.

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

Вы можете использовать операторы zip или forkjoin (они похожи, но не одинаковы), или вы можете связать ваши http-вызовы:

this.http.get1( url1, headers ).subscribe(
   data => {
      this.data1 = data;
      this.http.get2( url2, headers ).subscribe(
         data => {
            this.data2 = data;
         },
         error2{
            // do something on error2
         }
      )
   },
   error1 => {
      // do something on error1
   }
)

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

Редактировать: я нашел пример zip

     const  tpcomprob$ = this.data.getTPComprob( this.tpcomprobsId);
     const  comprobs$ = this.data.getComprobs(this.tpcomprobsId); 

     this.sbsComprobs = zip(tpcomprob$, comprobs$, (tpcomprob: any, comprobs: any) => ({tpcomprob, comprobs}))
                       .subscribe(pair => {
                          this.tpcomprob = pair.tpcomprob;
                          this.comprobs = pair.comprobs;

        },
        error => {this.httpError = error ;})
  });
0 голосов
/ 13 сентября 2018

Вы можете использовать rxjs/concat, посмотрите на этот пример: https://stackblitz.com/edit/angular-functions-in-sequence?file=src%2Fapp%2Fapp.component.ts

Это будет что-то вроде этого: во-первых, во-вторых, и так далее, это функции, которые возвращают Observables

let sequence = concat([
      this.first, 
      this.second, 
      this.afterSecond, 
      this.third]);

    sequence.subscribe(currentFunction => {
      currentFunction().subscribe(value => {
        this.values.push(value);
      })
    });
...