Rxjs combineLatest 确实在订阅中返回可观察的
Rxjs combineLatest does returning the observable with in the suscribe
在我需要根据 userid 进行调用后,我正在尝试获取 Userid 和 serviceId,这里的 serviceId 问题是它没有将 observable 返回给 ts。
Service.ts
function getData():observable<any>{
combineLatest([
this.activeSellService.getActiveSellServiceId(),
this.authService.getUserId(),
]).subscribe(([serviceId, userId]) => {
if (serviceId&& userId) {
const Url =
'users/' +
`${userId}` +
'/services/' +
`${serviceId}` +
'?value=test
return this.http.get<any>(this.endPoint.getUrl(encodeURI(Url)));
}
})
}
Component.ts:
this.service.getData().subscribe(data=>{console.log(data));
甚至它也不会在控制台中打印数据,因为该服务未返回可观察的。请帮我解决这个问题。否则我们可以在 rxjs 中使用不同的解决方案吗?
试试这个
function getData():observable<any>{
return combineLatest(
this.activeSellService.getActiveSellServiceId(),
this.authService.getUserId(),
).pipe(mergeMap([serviceId, userId]) => {
if (serviceId && userId) {
const Url =
'users/' +
`${userId}` +
'/services/' +
`${serviceId}` +
'?value=test
return this.http.get<any>(this.endPoint.getUrl(encodeURI(Url)));
}
})
}
注意 combinelatest 的参数,getData 中没有订阅
例如在 stackblitz 中:
https://stackblitz.com/edit/angular-rxjs-combinelatest-hjyfa6?file=src/app/app.component.ts
您需要使用像 switchMap
这样的高阶映射运算符来从一个可观察对象映射到另一个。此外,subscribe()
函数只接受回调,return 只接受包含订阅的 Subscription
对象。
此外,如果 if
条件失败,您也不会 returning 任何东西。您可以 return 像 RxJS 常量 EMPTY
这样的可观察对象,如果条件失败,它会立即完成订阅。
此外
observable<any>
必须是 Observable<any>
- 您还没有return退出函数。
- Typescript 中不需要
function
关键字。相反,您可以提及范围标识符。
- 您将字符串连接与模板文字混合在一起。虽然它在语法上没有错误,但我认为最好坚持使用其中之一。
- 从功能的上下文推测,我相信你希望发出一次请求并完成它。而不是
combineLatest
提供的数据流。在这种情况下,您可以改用 forkJoin
。但是请注意,forkJoin
仅在其所有来源完成时才会发出。
尝试以下方法
import { Observable, forkJoin, EMPTY } from 'rxjs';
import { switchMap } from 'rxjs/operators';
public getData(): Observable<any> {
return forkJoin([
this.activeSellService.getActiveSellServiceId(),
this.authService.getUserId(),
]).pipe(
switchMap(([serviceId, userId]) => {
if (!!serviceId && !!userId) {
const Url = `users/${userId}/services/${serviceId}?value=test`;
return this.http.get<any>(this.endPoint.getUrl(encodeURI(Url)));
} else {
return EMPTY;
}
})
);
}
在我需要根据 userid 进行调用后,我正在尝试获取 Userid 和 serviceId,这里的 serviceId 问题是它没有将 observable 返回给 ts。
Service.ts
function getData():observable<any>{
combineLatest([
this.activeSellService.getActiveSellServiceId(),
this.authService.getUserId(),
]).subscribe(([serviceId, userId]) => {
if (serviceId&& userId) {
const Url =
'users/' +
`${userId}` +
'/services/' +
`${serviceId}` +
'?value=test
return this.http.get<any>(this.endPoint.getUrl(encodeURI(Url)));
}
})
}
Component.ts:
this.service.getData().subscribe(data=>{console.log(data));
甚至它也不会在控制台中打印数据,因为该服务未返回可观察的。请帮我解决这个问题。否则我们可以在 rxjs 中使用不同的解决方案吗?
试试这个
function getData():observable<any>{
return combineLatest(
this.activeSellService.getActiveSellServiceId(),
this.authService.getUserId(),
).pipe(mergeMap([serviceId, userId]) => {
if (serviceId && userId) {
const Url =
'users/' +
`${userId}` +
'/services/' +
`${serviceId}` +
'?value=test
return this.http.get<any>(this.endPoint.getUrl(encodeURI(Url)));
}
})
}
注意 combinelatest 的参数,getData 中没有订阅
例如在 stackblitz 中:
https://stackblitz.com/edit/angular-rxjs-combinelatest-hjyfa6?file=src/app/app.component.ts
您需要使用像 switchMap
这样的高阶映射运算符来从一个可观察对象映射到另一个。此外,subscribe()
函数只接受回调,return 只接受包含订阅的 Subscription
对象。
此外,如果 if
条件失败,您也不会 returning 任何东西。您可以 return 像 RxJS 常量 EMPTY
这样的可观察对象,如果条件失败,它会立即完成订阅。
此外
observable<any>
必须是Observable<any>
- 您还没有return退出函数。
- Typescript 中不需要
function
关键字。相反,您可以提及范围标识符。 - 您将字符串连接与模板文字混合在一起。虽然它在语法上没有错误,但我认为最好坚持使用其中之一。
- 从功能的上下文推测,我相信你希望发出一次请求并完成它。而不是
combineLatest
提供的数据流。在这种情况下,您可以改用forkJoin
。但是请注意,forkJoin
仅在其所有来源完成时才会发出。
尝试以下方法
import { Observable, forkJoin, EMPTY } from 'rxjs';
import { switchMap } from 'rxjs/operators';
public getData(): Observable<any> {
return forkJoin([
this.activeSellService.getActiveSellServiceId(),
this.authService.getUserId(),
]).pipe(
switchMap(([serviceId, userId]) => {
if (!!serviceId && !!userId) {
const Url = `users/${userId}/services/${serviceId}?value=test`;
return this.http.get<any>(this.endPoint.getUrl(encodeURI(Url)));
} else {
return EMPTY;
}
})
);
}