我有一个简单的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)
答案 0 :(得分:3)
好的,所以关于可观察流中的数组的事情是,它们就像流中的任何其他单个值一样。您的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
然而,上述工作不会起作用,因为延迟会将整个流程按时间而不是每个项目进行移动,因此要完成展平和分离,我们需要更加明确,从这个答案中得出: Separate observable values by specific amount of time in 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());
答案 1 :(得分:2)
您可以再次使用flatMap' delay()
,
return this.contributorsService.getContributors(payload.pageNumber)
.flatMap(x => x) // to single values
.flatMap(x => Observable.of(x).delay(Math.random() * 500)) // apply delay
const Observable = Rx.Observable
Observable.of([1,2,3])
.flatMap(x => x)
.flatMap(x => Observable.of(x).delay(Math.random() * 500))
.subscribe(console.log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.3/Rx.js"></script>