如何使用 Rxjs 订阅日期变化
How to subscribe to date chage with Rxjs
我找不到一个使用 Rxjs 的“简单”示例,演示了我们如何将天数变化作为一个事件来监听。
例如,假设每次进入新的一天我都必须执行某些方法。我怎样才能用反应范式来处理这个问题并订阅时间事件?
只需使用 timer();
或 interval()
Observable,它可以在您想要的任何时间间隔发射,并在当天的每次发射检查中发射。 F.ex。这将每秒检查当天:
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()
函数,更可靠的方法是存储最后一天并检查当前日期是否不同。
我已经通过创建一个延迟到订阅发生的可观察对象解决了这个问题,然后计算时间并寻找最近的午夜来发出事件。
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);
});
}
然后可以将此可观察对象与 reapeatWhen
运算符一起使用,以在发出新的一天事件时重复之前的流。
我找不到一个使用 Rxjs 的“简单”示例,演示了我们如何将天数变化作为一个事件来监听。
例如,假设每次进入新的一天我都必须执行某些方法。我怎样才能用反应范式来处理这个问题并订阅时间事件?
只需使用 timer();
或 interval()
Observable,它可以在您想要的任何时间间隔发射,并在当天的每次发射检查中发射。 F.ex。这将每秒检查当天:
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()
函数,更可靠的方法是存储最后一天并检查当前日期是否不同。
我已经通过创建一个延迟到订阅发生的可观察对象解决了这个问题,然后计算时间并寻找最近的午夜来发出事件。
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);
});
}
然后可以将此可观察对象与 reapeatWhen
运算符一起使用,以在发出新的一天事件时重复之前的流。