【发布时间】:2020-12-04 13:20:12
【问题描述】:
我有一个服务,它首先执行 getName 函数,然后当一些数据进入 getPlace 函数的 else 块时,而不是常规对象,我得到一个订阅者(如您在屏幕截图中所见),尽管理论上我订阅了我分配值的更改。它可以修复吗?
【问题讨论】:
-
欢迎,请将您的代码设置为文本模式。
我有一个服务,它首先执行 getName 函数,然后当一些数据进入 getPlace 函数的 else 块时,而不是常规对象,我得到一个订阅者(如您在屏幕截图中所见),尽管理论上我订阅了我分配值的更改。它可以修复吗?
【问题讨论】:
正如其他人所说,您不能将 http 请求(http.get)视为过程代码。 http 请求是异步的,.pipe() 方法中的代码仅在服务器返回数据后执行。
因此,您的 getPlace() 方法将无法通过调用 _getPlace() 方法简单地返回 data。
而不是与这种工作方式作斗争并尝试“修复”它。我建议您将 both 作为 Observables 处理。
我在类似情况下的代码如下所示:
服务
import { Observable, of, throwError } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';
getProducts(): Observable<IProduct[]> {
if (this.products) {
return of(this.products);
}
return this.http.get<IProduct[]>(this.productsUrl)
.pipe(
tap(data => console.log('All Products', JSON.stringify(data))),
tap(data => this.products = data),
catchError(this.handleError)
);
}
组件
this.productService.getProducts().subscribe({
next: (products: IProduct[]) => {
this.products = products;
},
error: err => this.errorMessage = err
});
这里,如果数据已经被缓存,它使用 RxJS of 操作符将数据转换回 Observable。
这样你可以订阅 getProducts 的结果,你会得到缓存的数据或检索到的数据。
注意:另一种选择是以声明方式使用 RxJS 并利用 RxJS shareReplay(1) 运算符自动为您提供缓存。有关此技术的更多信息,请查看:https://www.youtube.com/watch?v=Z76QlSpYcck&t=517s
【讨论】:
您必须订阅获取价值的功能
public nameList :any;
this.getPlace(placeId).subscribe(data => {
//data hold your expected response
this.nameList =data;
});
【讨论】:
Observable 是异步的,javascript 使用单线程环境。 如果 javascript 线程检测到任何异步任务,则将任务交给封闭环境(浏览器等)以在单独的线程中执行它。 所以你的代码是这样运行的。
这就是返回的数据为空的原因。
要解决您的问题,请使用map 而不是subscribe
if(this._place.has(placeId)){
return this._places.get(placeId)
} else {
let data: any = this.getPlace(placeId).map( place => {
//do something here
//return something
}).first()
return data;
}
【讨论】: