我有一个简单的 HTTP 调用:
getContributors(pageNumber): Observable<any> {
const url = `${this.apiBaseUrl}/orgs/angular/public_members?&page=${pageNumber}`;
const requestOptions = this.getRequestOptions();
return this.http.get(url, requestOptions);
}
调用是在ngrx effect
.
...
return this.contributorsService.getContributors(payload.pageNumber)
.delay(new Date(Date.now() + Math.random() * 500))
... // mergeMap etc. here
然而,虽然 HTTP 调用返回一个包含多个值的数组,但它们无论如何都是一次性发出的。
我是否误解了delay()
操作员的目的(在这种情况下,我如何达到预期的结果?)还是我以错误的方式使用它?
注意:我导入了增强 import 'rxjs/add/operator/delay';
更新:澄清一下,预期结果是:我希望拆分数组,并在给定(恒定)时间分别发出数组中的每个值
更新 2:所以,数组实际上是由
.flatMap(data => Observable.from(data))
事实上,如果
.do(value => console.log(value))
每个值都单独打印。
但是,如果不是 .do(....)
我放
.delay(3000)
.do(() => console.log(new Date())
我可以看到的延迟是不尊重所有(除它实际上等待3000发出的事实所有的值在没有延迟序列-一排,即多个console.logs)
好的,关于可观察流中的数组,它们就像流中的任何其他单个值一样。您的 http 调用返回一个数组值,因此它将整个数组作为一个值返回,并且一次全部执行。如果你想把一个数组拆分成多个值,你当然可以这样做,但是你需要告诉 rxjs 这样做,我的首选方法是使用 flatMap ,如下所示:
.flatMap(arrVal => Observable.from(arrVal))
此操作会将您的数组值展平为可观察的值流,因此您可以像这样使用它:
return this.contributorsService.getContributors(payload.pageNumber)
.flatMap(data => Observable.from(data))
.delay(Math.random() * 500) // you should just feed a ms value to delay if you want constant time interval, date parameters mean delay till that date, so they'll all just flow through at that date
但是,上述方法不起作用,因为延迟会按时间而不是每个项目移动整个流,因此要完成展平和分离,我们需要更明确一点,从这个答案中汲取:按特定的可观察值分离RxJS 中的时间
return this.contributorsService.getContributors(payload.pageNumber)
.switchMap(data => Observable.interval(Math.random() * 500)
.take(data.length)
.map(i => data[i]))
通过这种方式,我们以均匀的间隔手动展平数组。
此版本也可以使用,并且可能会感觉更干净:
return this.contributorsService.getContributors(payload.pageNumber)
.flatMap(data => Observable.from(data))
.zip(Observable.interval(Math.random() * 500), (d,i) => d)
这只是使用 zip 操作符将每个项目与一个在间隔上发出的 observable 压缩。
现在,您应该看到每个数组项的期望行为以恒定间隔一次通过一个。但是,如果您使用的是 http 服务,则可能需要在响应中调用 .json() 以获取数组形式的值,如下所示:
return this.http.get(url, requestOptions).map(res => res.json());
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句