【问题标题】:Rx : Force observable to take at least N seconds to completeRx :强制 observable 至少需要 N 秒才能完成
【发布时间】:2017-10-07 15:12:08
【问题描述】:

我正在为我的应用制作启动画面。我希望它在进入主屏幕之前至少持续 N 秒。

我有一个 Rx 变量 myObservable 从服务器或本地缓存返回数据。如何强制myObservable至少 N 秒内完成?

myObservable
// .doStuff to make it last at least N seconds
   .subscribe(...)

【问题讨论】:

  • subscribe 之前添加delay(new Date(Date.now() + 6000)) 是另一个(稍微简单一些)选项,因为delay 将接受绝对的Date

标签: rxjs rx-java reactivex


【解决方案1】:

您可以使用forkJoin 等待两个 Observable 完成:

Observable.forkJoin(myObservable, Observable.timer(N), data => data)
  .subscribe(...);

对于没有弃用结果选择器功能的 RxJS 6:

forkJoin(myObservable, Observable.timer(N)).pipe(
  map(([data]) => data),
)
.subscribe(...);

编辑:如 cmets 中所述,只有一个参数的 Observable.timer(N) 将在发出一项后完成,因此不需要使用 take(1)

【讨论】:

  • 谢谢马丁,你知道 rxjava 中的 forkjoin() 等价物吗?
  • take(1) 操作符是 noop,考虑到计时器只会发出 1 个值
  • 这不是真的,forkJoin 将来自所有源 Observable 的值传递到选择器中,所以 data => data 只是 (data, i) => data 的一个较短的符号。如果您不使用选择器,则进一步发出的值将是 [data, i]
  • 对于 RXJS 6 forkJoin(myObservable, timer(N)).subscribe(([val, _]) => {...})
【解决方案2】:

Angular 7+ 的 forkjoin 示例

我喜欢在我的开发系统上构建更高的延迟,因为我认为生产会更慢。 Observable.timer 似乎不再可用,但您可以直接使用 timer

forkJoin(

  // any observable such as your service that handles server coms
  myObservable,

  // or http will work like this
  // this.http.get( this.url ),

  // tune values for your app so very quick loads don't look strange
  timer( environment.production ? 133 : 667 ),

).subscribe( ( response: any ) => {

  // since we aren't remapping the response you could have multiple
  // and access them in order as an array
  this.dataset = response[0] || [];

  // the delay is only really useful if some visual state is changing once loaded
  this.loading = false;

});

【讨论】:

  • 我发现您在代码中输入的 cmets 很有帮助,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-24
  • 1970-01-01
  • 1970-01-01
  • 2011-03-25
  • 1970-01-01
相关资源
最近更新 更多