我正在开发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知之甚少。任何人都可以帮助我吗?
答案 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
替换为所需的数字来解决原始问题。