#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 отвечает на ваш вопрос, я хочу добавить некоторые моменты, так как кажется, что вы не знакомы с асинхронными и наблюдаемыми концепциями…
- HTTP — запрос-это
async
вызов. Это означает, что когда вы делаете http-запрос, браузер не будет ждать ответа, а продолжит выполнение кода после этого вызова. И когда ответ доступен, вызывается метод обратного вызова или подписки. - Итак, в приведенном выше фрагменте кода сначала эта строка выполняется в методе:
пусть ответ = новый ответ();
Затем запрос отправляется на сервер. Что, по сути, и есть этот код
это.HttpClient.get(url)
Затем, как указано в пункте 1, выполняется следующая инструкция, которая
вернуть ответ на запрос;
Затем в какой-то момент времени запрос завершится и будет вызван метод подписки. Выполнение следующего кода
Ответьте.данные = HttpResponse.данные;
Но так как вы не ждете до этого момента, чтобы вернуть данные вызывающему абоненту из file1.ts. Данные будут не определены в ответе на запрос
this.appResonse = этот.файл1.get1(конечная точка);
- Поэтому, когда вы хотите получать данные от таких асинхронных вызовов, вам придется возвращать обещание или Наблюдаемое, что означает, что данные будут доступны в какой-то момент в будущем, и вызывающий метод будет уведомлен, когда данные будут доступны. Поэтому в вашем случае вам придется вернуть наблюдаемый из
file2.ts
и подписаться наfile1.ts
- Таким образом, ваш код может быть
**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. Отредактировал ответ, чтобы включить примеры