【发布时间】:2021-02-12 14:34:32
【问题描述】:
我找不到一个使用 Rxjs 的“简单”示例,演示我们如何将天的变化作为一个事件来监听。
例如,假设我每次进入新的一天时都必须执行某些方法。我如何使用响应式范式来解决这个问题并订阅时间事件?
【问题讨论】:
标签: javascript rxjs reactive
我找不到一个使用 Rxjs 的“简单”示例,演示我们如何将天的变化作为一个事件来监听。
例如,假设我每次进入新的一天时都必须执行某些方法。我如何使用响应式范式来解决这个问题并订阅时间事件?
【问题讨论】:
标签: javascript rxjs reactive
只需使用timer(); 或interval() Observable,它们可以在您想要的任何时间间隔以及当天的每次发射检查中发射。前任这将每秒检查当前日期:
timer(0, 1000).pipe(
tap(() => {
const date = new Date();
const currentDay = date.getDate();
})
)
每秒检查当前日期没有多大意义,但当前时间可能比第二天早一秒,因此可能需要。为了改善这一点,您可以在日期变化时切换到新的 Observable,它将在 23 小时 59 分钟后发出:
const source$ = timer(0, 1000).pipe(
switchMap(() => {
const dayState = this.getDayState();
if (dayState && dayState.ends) {
return timer(0, (1000 * 60 * 60 * 23) + (1000 * 60 * 59)).pipe(
switchMap(() => this.source$)
)
}
return this.source$;
})
)
function getDayState(): {stars?: boolean, ends?: boolean} {
const date = new Date();
const hours = date.getHours();
const minutes = date.getMinutes();
if (hours === 23 && minutes === 59) {
return { ends: true };
} else if (hours === 0 && minutes === 1) {
return { starts: true };
}
}
这是一个非常粗略的例子。另外,目前我不知道浏览器将如何处理这个长期订阅。您可能需要做一些变通方法,例如强制浏览器重新加载或添加其他检查,以便您可以依赖此流。另外,不是使用getDayState() 函数,更可靠的方法是存储最后一天并检查当前日期何时不同。
【讨论】:
我通过创建一个延迟到订阅发生的 observable 解决了这个问题,然后计算时间并寻找最近的未来午夜来发出事件。
function newSolarDayObserver() {
return defer(() => {
const timeAtSubscription = new Date();
const nextDay = new Date();
// get the nearest midnight in future
nextDay.setHours(24, 0, 0, 0);
const initialDelay = nextDay.getTime() - timeAtSubscription.getTime();
// repeat every 24 hours and 1 minute
const repeat = 1000 * 60 * 61 * 24;
return timer(initialDelay, repeat);
});
}
这个 observable 然后可以与 reapeatWhen 运算符一起使用,以在发出新的一天事件时重复上一个流。
【讨论】: