Как вернуть данные из функции, реализующей наблюдаемые

#angular #observable

Вопрос:

У меня есть требование, как показано ниже

У меня есть функция (скажем, в файле 2.ts), которая делает наблюдаемыми HTTP-запросы GET и возвращает объект AppResponse, заполненный HTTP-ответом. вот код. я хочу, чтобы объект ответа в файле 1.ts был заполнен вызовом file2.ts get1. Как этого добиться?

 **file1.ts**

  getProfile() {
    this.appResonse = this.file1.get1(endPoint);
  }

**file2.ts**
  get1(endPoint: string): AppResponse {
    let appResponse = new AppResponse();

    this.httpClient.get<IHttpResponse>(url).subscribe((httpResponse: IHttpResponse) => {
        appResponse.data = httpResponse.data;
    });

    return appResponse;
  }
 

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

1. в файле 2 вы можете вернуть Observable<AppResponse> вместо AppResponse , затем в файле 1 назначить наблюдаемую локальную переменную

Ответ №1:

Хотя ответ akirus отвечает на ваш вопрос, я хочу добавить некоторые моменты, так как кажется, что вы не знакомы с асинхронными и наблюдаемыми концепциями…

  1. HTTP — запрос-это async вызов. Это означает, что когда вы делаете http-запрос, браузер не будет ждать ответа, а продолжит выполнение кода после этого вызова. И когда ответ доступен, вызывается метод обратного вызова или подписки.
  2. Итак, в приведенном выше фрагменте кода сначала эта строка выполняется в методе:

пусть ответ = новый ответ();

Затем запрос отправляется на сервер. Что, по сути, и есть этот код

это.HttpClient.get(url)

Затем, как указано в пункте 1, выполняется следующая инструкция, которая

вернуть ответ на запрос;

Затем в какой-то момент времени запрос завершится и будет вызван метод подписки. Выполнение следующего кода

Ответьте.данные = HttpResponse.данные;

Но так как вы не ждете до этого момента, чтобы вернуть данные вызывающему абоненту из file1.ts. Данные будут не определены в ответе на запрос

this.appResonse = этот.файл1.get1(конечная точка);

  1. Поэтому, когда вы хотите получать данные от таких асинхронных вызовов, вам придется возвращать обещание или Наблюдаемое, что означает, что данные будут доступны в какой-то момент в будущем, и вызывающий метод будет уведомлен, когда данные будут доступны. Поэтому в вашем случае вам придется вернуть наблюдаемый из file2.ts и подписаться на file1.ts
  2. Таким образом, ваш код может быть
 **file1.ts**

  getProfile(): void {
    this.file1.get1(endPoint).subscribe(appResponse => this.appResponse = appResponse);
  }

**file2.ts**
  get1(endPoint: string): Observable<AppResponse> {
    return this.httpClient.get<IHttpResponse>(url)
                   .pipe(
                      map((httpResponse: IHttpResponse) => {
                             let appResponse = new AppResponse();
                             appResponse.data = httpResponse.data;
                             return appResponse;
                      });
                    );
  }
 

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

1. Во-первых, какое объяснение. Спасибо @saivishnu. Позвольте мне попробовать это.

2. в какой библиотеке находится «карта»? Это показывает мне ошибку. я импортировал import { Observable } from 'rxjs';

3. map является оператором из rxjs. импорт {карта} из rxjs/operators

4. angular запрашивает функцию, объявленный тип которой ни «void», ни «любой» не должен возвращать значение

5. Большое вам спасибо @saivishnu!. Отметив это как Принятый ответ.

Ответ №2:

файл1.ts

 export class ComponentOne{

    appResponse$: Observable<AppResponse>;
    
    constructor(private serviceOne: ServiceOne){
        this.appResponse$ = this.serviceOne.get1();
        
        this.appResponse$.pipe(
            map(httpResponse => httpResponse.data)
        ).subscribe(data =>{
            console.log(data);
        });
    }
    
}
 

файл2.ts

 @Injectable({
    providedIn: 'root'
})
export class ServiceOne{
    get1(endPoint: string): Observable<AppResponse> {
        return this.httpClient.get<IHttpResponse>(url);
    }
}
 

Ответ №3:

Нормальный подход состоит в том, чтобы иметь:

 return this.httpClient.get(url);
 

в файле 2, а затем подпишитесь на этот ответ в файле 1, установив значение appResponse для данных ответа.

Если по какой-то причине вам действительно нужно подписаться в файле 2, вы можете либо вернуть обещание, которое будет выполнено при получении данных, либо иметь какую-то пару наблюдатель/подписчик, на которую вы подписываетесь в файле 1 при получении данных.

Все это всего лишь дополнительные шаги, которые могут помочь вам сохранить эти данные в файле 2, а также отправить их в файл 1, но если это не так, то следует просто подписаться в файле 1.

Изменить: Пример альтернативных вариантов

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

1. Спасибо за ответ @Akirus. Я хочу подписаться только на файл2. не могли бы вы помочь с примером кода обещания или наблюдателя/подписчика, о котором вы упомянули.

2. Отредактировал ответ, чтобы включить примеры