如何检查可观察倒数计时器是不是已完成?

Posted

技术标签:

【中文标题】如何检查可观察倒数计时器是不是已完成?【英文标题】:How to check if observable countdown timer has completed?如何检查可观察倒数计时器是否已完成? 【发布时间】:2018-01-24 19:48:31 【问题描述】:

我有一个简单的 angular 4 倒数计时器

import Observable from 'rxjs/Observable';
import 'rxjs/add/observable/timer';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';

countDown;
counter = 60;
enableButton:boolean = false;

this.countDown = Observable.timer(0,1000).take(this.counter).map(() => --
 this.counter);

当这个 observable 完成后,我想将 enableButton 设为布尔值。

我应该如何编写该代码?请帮忙

这是一个 plunker 链接,我在我的项目中使用它 https://plnkr.co/edit/TWMIEd1UykUdUC37qyFK?p=preview

【问题讨论】:

我刚刚用你的 plunker 更新了我的答案 @Michael -- 查看我的回答 ***.com/a/45718118/561731 依赖于使用可观察扫描而不是更新组件计数器。 @Neal -- 我也接受你的回答,非常感谢你花时间回答。 @MichaelJoshua 在这个系统中你只能“接受”一个答案 ;-) 做出你的选择 【参考方案1】:

在视图中:

<button [disabled]="counter !== 0">OK</button>

在课堂上:

  countDown;
  counter = 10; // change accordingly
  tick = 1000;
  constructor() 
  this.countDown = Observable.timer(0, this.tick)
      .take(this.counter)
      .map(() => --this.counter)
  

plunker

【讨论】:

非常感谢,你拯救了我的一天 这样的评论让我很开心 :) 不客气【参考方案2】:

您可以充分利用扫描和异步:

@Component(
  selector: 'my-app',
  template: ` 
    <div>
      <h1>Countdown timer</h1>
      <h2>countDown | async</h2>
      
      <button [disabled]="(countDown | async) === 0">My button</button>
    </div>
  `,
)
export class App 
  
  countDown;
  counter = 10;
  
  constructor() 
    
    this.countDown = Observable.timer(0,1000)
      .scan((current, next) => this.counter - next)
      .takeWhile(counter => counter >= 0);
  

这是现场版:https://plnkr.co/edit/bKESzNK1wqbtPmQk4TUT?p=preview

因此,您使用 scan 来保持对本地版本的计数,而不是更新全局计数器(因为计时器按顺序返回数字)

旧答案

您可以使用.takeWhile 运算符

this.countDown = Observable.timer(0,1000)
    .take(this.counter)
    .map(() => --this.counter)
    .takeWhile(counter => counter >= 0);

这里是更新的 plnkr:https://plnkr.co/edit/Z6K5Yt2tDS4MKbgIoujc?p=preview

您实际上不需要.take,只需这样做:

this.countDown = Observable.timer(0,1000)
  .map(() => this.counter--)
  .takeWhile(counter => counter >= 0);

https://plnkr.co/edit/L38t3LYON9DszW5N2MjA?p=preview

【讨论】:

我认为仍然不能按照 OP 的意愿工作。请参阅:plnkr.co/edit/VW47EZDnRPzvUX0hP3Rs?p=preview @Sampath 你为什么要订阅?这使得模板中的 aync 不再起作用 但是他需要启用这个变量没有enableButton?没有subscribing他怎么办? 谢谢@Sampath :-D 是的,但如果 OP 需要,很容易可逆。不需要为 OP 编写所有代码 ;-)【参考方案3】:

http://reactivex.io/documentation/operators/subscribe.html第三个参数

你可以这样做:

this.countDown = Observable
  .timer(0, 1000)
  .take(this.counter)
  .map(() => --this.counter);

this.countDown.subscribe(() => , () => , () => (this.enableButton = true))

或者像这样:

<button *ngIf="!(countDown | async)"><button>
<button *ngIf="this.counter"><button>

【讨论】:

以上是关于如何检查可观察倒数计时器是不是已完成?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 kivy 中创建 60 秒倒数计时器

如何创建在使用 AnimationController 创建的倒数计时器期间发出的警报?

当活动暂停时,如何正确停止倒数计时器中的媒体播放器?

如何以最新的 API 级别在服务中运行我的倒数计时器?

如何在Android中制作倒数计时器?

刷新网页时如何防止倒数计时器重置?