setInterval vs Observable的timer方法,最好创建计时器 [英] setInterval vs Observable's timer method, which is better to create timer

查看:330
本文介绍了setInterval vs Observable的timer方法,最好创建计时器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须在Angular中创建一个计时器,目前我正在通过Observable进行操作,如下所示:

I have to make a timer in Angular, currently i'm doing it by Observable as follows:

  timer: Observable<any> = Observable.timer(0, 990);
  timerSubscription: Subscription;

  this.timerSubscription = this.timer.subscribe((value) => {
    this.tickerFunc();
  }); // inside ngOnInit

  tickerFunc () {
    this.timeNow++;

    this.timeNowInMinutes = Math.floor(this.timeNow / 60);

    if (this.timeNow >= this.TimeLimit) {
      this.finishtest();
    }
  }

所以我在这里有两个问题:

So i have two Questions here:

1)使用Observable的计时器是否不错,还是应该使用setInterval()方法,还是两者具有相同的性能?

1) Is Using Observable's timer is good, or should i use setInterval() method, or both has the same performance?

2)如您所见,每次计时器计时时,我都必须进行两次计算:

2) As you can see, for each time the timer ticks, i have to do two calculations:

第一:我必须将秒转换为分钟.

first: i have to convert the seconds to minutes.

第二步:我必须检查计时器是否已达到时间限制,如果需要,请取消订阅计时器.

Second: I have to check if the timer has reached the time limit, and if the case, to unsubscribe the timer.

我的两个问题都与使计时器尽可能准确有关. (尽可能接近实时).正如您所注意到的,我给了tim间隔990毫秒而不是1000毫秒,以弥补由于tickerFunc()主体内部的计算而发生的时间损失.

Both of my questions are related to make a timer as accurate as possible. (as close accurate to real-time as possible). And as you can notice, i have given the tim interval of 990 milliseconds instead of 1000 milliseconds to cover the time loss occured because of the calculations inside the tickerFunc() body.

推荐答案

严格地在给定的时间间隔后执行一个功能,Observable可能有点过大,但是由于您需要操纵该时间间隔,因此这将是一个很好的用例:

Strictly for executing a function after a given interval an Observable might be a bit overkill, but since you need to manipulate that interval it should be a good use case:

import { timer } from 'rxjs/observable/timer';
import { take } from 'rxjs/operators';

timer(0, 990).pipe(
    take(this.timeLimit),
)
.subscribe((v) => this.timeNowInMinutes = Math.floor(v / 60),
           (err) => console.log(err),
           () => this.finishTest());

注意,我使用了take运算符仅具有所需的事件数,并在完成的回调中调用finishTest.

Notice I've used the take operator to only have the required number of events and call finishTest in the completed callback.

我使用了RxJs 5.5中提供的新的lettable运算符,其代码将与旧版本非常相似.

I've used the new lettable operators available from RxJs 5.5, code will be quite similar with the old version.

您还可以删除订阅并在Angular中使用异步管道,但是在这种情况下,对finishTest的完成调用有点隐蔽:

You can also remove the subscription and use the async pipe in Angular, but in this case the completion call to finishTest is a bit hidden away:

const $timerStream = timer(0, 990).pipe(
    take(this.timeLimit),
    map(v => Math.floor(v + 60 / 60)),
    tap(v => v === this.timeLimit ? this.finishTest() : undefined),
);

您可以使用map将值转换为所需的值(注意,我在其中添加了+ 60以确保它们正在增加,您可以添加timeNow中具有的任何初始值),并在其中使用异步管道呈现此值的模板. tap方法(以前称为do)将检查它是否是发出的最后一个项目,如果是,则调用finishTest.

You can use map to transform the values to what you need (notice I've added a + 60 there to make sure they are increasing, you can add whatever initial value you had in timeNow) and you use the async pipe in the template to render this value. The tap method (previously known as do) will check if it's the last item emitted and call finishTest if it is.

这篇关于setInterval vs Observable的timer方法,最好创建计时器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆