当以Observables结束或以任何方式在Angular2中时,需要将计时器倒计时重置为60

时间:2017-08-29 08:20:22

标签: rxjs angular2-observables

我正在开发Angular2中的竞价网站。我需要为每个产品定时器,从60秒开始,当它变为0时,它再次重置为60。

public class FCM_IIDS extends FirebaseInstanceIdService {

    final String token_preference_key = "fcm_token";

    final static String infoTopicName = "info";

    @Override
    public void onTokenRefresh() {
        super.onTokenRefresh();
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        sharedPreferences.edit().putString(token_preference_key, FirebaseInstanceId.getInstance().getToken()).apply();


        FirebaseMessaging.getInstance().subscribeToTopic(infoTopicName);
    }
}

计数器从60秒开始,最后以0结束。但我无法实现复位部分,当其值变为0时,再次重新分配60以进行计数。

我对RxJs中的Obervables知之甚少。任何人都可以帮助我吗?

1 个答案:

答案 0 :(得分:1)

欢迎使用Stack Overflow!

我们可以使用一些数学来实现这一目标。 请阅读奖励部分以查看备选方案

this.countDown = Observable
  .timer(0, 1000) // emits 0, 1, 2, 3, 4, 5, 6, 7, 8...
  .map(tick => 60 - (tick % 60)); // emits 60, 59, 58... 0, 60, 59...

我们将其余的除法除以60 - tick % 60

1 % 60 = 1
2 % 60 = 2
...
60 % 60 = 0
61 % 60 = 1
...

如果我们想要从60开始倒数​​,那么我们需要从60减去其余的除法。

奖金(回答评论中的问题)

如果你想以随机数开头,你必须在observable中保留某种状态。 scan运算符用于此目的。在这种情况下,使用timer运算符是一种过度杀手,我们可以使用interval代替。

function getRandomNumber() { // returns a random integer from 1 to 60
    return Math.floor(Math.random() * 60) + 1;
}

Observable
      .interval(1000) // emits every second
      // `scan` works like `reduce` method of the array
      // it keeps its own internal state in `acc`
      // `acc` initial value is random and when it reaches 1, it has a new random integer assigned to it again
      .scan(acc => acc === 1 ? getRandomNumber() : acc - 1, getRandomNumber());
      // emits e.g. 5, 4, 3, 2, 1, 10, 9, 8, 7, 6...

从技术上讲,您可以通过将getRandomNumber替换为所需的数字来解决原始问题。