Chr*_*ler 8 javascript observable rxjs typescript angular
我在Angular 4应用中有类似的东西(出于示例的原因,我删除了代码)
@Injectable()
export class SomeService {
constructor(
private http: Http
) {
}
get(id: number) {
return this.http.get('http://somedomain/somemodel/${id}.json');
}
}
Run Code Online (Sandbox Code Playgroud)
一些组件使用它来进行API调用。
constructor(private someService: SomeService) {}
...
someMethod() {
// code here...
this.someService.get(2).subscribe( someHandlerFunction );
}
someOtherMethod() {
// more code here...
this.someService.get(2).subscribe( someHandlerFunction );
}
Run Code Online (Sandbox Code Playgroud)
问题是我不知道何时调用someMethod()和someOtherMethod()。有时可能会同时调用它们,然后,我的API将被调用两次。我要查找的是是否有任何方法可以更改我的服务以仅在X数量的时间后执行此请求。我尝试使用去抖动:
get(id: number) {
return this.http.get(`http://somedomain/somemodel/${id}.json`).debounceTime(10000);
}
Run Code Online (Sandbox Code Playgroud)
期望(在这种情况下)此HTTP get请求将仅在10秒后重复,如果在10秒内发出请求,则该请求将不会重复,但是observable会发出最后一个值。但这没有用。有小费吗?
PS:我知道我可以使用某种标志来控制它,但是只要它不能很好地缩放,就不能这样做。我有许多带有许多HTTP请求的服务。
有什么想法吗?
小智 5
Debounce 应该用在调用 http 服务的 observable 上,而不是用在 http 请求本身上。所以例如:
someObservable
.valueChanges
.debounceTime(1000)
.subscribe(// Call the http service here)
Run Code Online (Sandbox Code Playgroud)
此处对先前提出的问题提供了更好的解释。
您可以使用 RxJS 缓存结果,然后设置一个间隔,每隔几秒清除一次缓存,从而允许发出新请求。当您不希望用户每次加载页面时都重新查询数据库时,尤其是没有添加任何新内容时,这通常是一个好方法。
这是一种比其他答案稍微冗长的方法,但它提供了一些好处:
debounceTime,您不仅仅是阻止请求。您正在阻止请求并提供缓存的结果。如果您只阻止请求,您将不会得到任何结果。通过我的方法,如果需要,您仍然可以获得结果,使用最后获取的结果 - 只是在您允许之前它不会发出新请求。缓存结果:
Class ProjectService {
private cachedProjects: Observable<Project[]>;
all(): Observable<Project[]> {
if (!this.cachedProjects) {
this.cachedProjects = this.httpService.get(`${this.url}/project`)
.map(res => res.data.map(project => new Project(project)))
.publishReplay()
.refCount();
}
return this.cachedProjects;
}
}
Run Code Online (Sandbox Code Playgroud)
当您致电服务时:
this.projectService.all().subscribe((projects: Project[]) => {
// 'projects' will be fetched the first time this is called,
// and any subsequent requests will use the 'cachedProjects'
// stored in the service, until the interval sets it to null.
});
Run Code Online (Sandbox Code Playgroud)
现在,为了确保它仅偶尔阻止 HTTP 调用,您可以在服务上设置一个时间间隔。按如下方式修改您的服务:
Class ProjectService {
private cachedProjects: Observable<Project[]>;
constructor() {
// Put this in a function or something.
setInterval(() => {
this.cachedProjects = null;
}, 5000);
}
all(): Observable<Project[]> {
if (!this.cachedProjects) {
this.cachedProjects = this.httpService.get(`${this.url}/project`)
.map(res => res.data.map(project => new Project(project)))
.publishReplay()
.refCount();
}
return this.cachedProjects;
}
}
Run Code Online (Sandbox Code Playgroud)
所以现在你可以每 5 秒发出一个新请求,否则将使用缓存的项目。
| 归档时间: |
|
| 查看次数: |
5861 次 |
| 最近记录: |