我在相关应用程序中使用以下库:Angular 4.x,ngrx 4.x,rxjs 5.4.x
我有一个api,我需要每5分钟轮询一次。用户还可以手动刷新数据。该数据存储在ngrx存储中。我正在使用ngrx效果,因此通过调度类型为' FETCH'的行动来检索数据。
我想设置一个rxjs流,它将调度' FETCH'对ngrx商店的行动。它将是一个滑动的5分钟计时器,当用户手动更新商店时会重置。订阅时,流最初应该发出一个值。
我不确定如何重置计时器。在普通的javascript中,我会做类似以下的事情:
console.clear();
let timer;
let counter = 0;
function fetch() {
console.log('fetch', counter++);
poll();
}
function poll() {
if (timer != null) {
window.clearTimeout(timer);
}
timer = window.setTimeout(() => {
console.log('poll');
fetch();
}, 5000);
}
function manualGet() {
console.log('manual');
fetch();
}
fetch();

<button onClick="manualGet()">Get Data</button>
&#13;
问题:当另一个流再次像示例一样发出时,如何在重置的时间间隔内发光?
答案 0 :(得分:3)
您需要两个组件到您的流 - 计时器和一些用户输入。所以让我们从用户输入开始。我假设有一些可以点击的按钮:
const userInput$ = Observable.fromEvent(button, 'click');
现在我们要启动一个计时器,每次userInput$
发出时都会重置。我们可以使用
userInput$.switchMap(() => Observable.timer(0, 5000));
但是,我们还希望在没有用户必须首先单击按钮的情况下启动此流。但这也不是问题:
userInput$.startWith(null);
现在我们把它们放在一起:
Observable.fromEvent(button, 'click')
.startWith(null)
.switchMap(() => Observable.timer(0, 5000))
.subscribe(() => dispatchFetch());
注意我正在关注使用5秒计时器的例子,而不是5分钟的计时器(你在问题中提到过。)
答案 1 :(得分:0)
在vanilla JS中写完之后,我意识到计时器的来源应该是数据。我正在努力弄清楚源头是什么。显然它不能是计时器,因为我需要重置它。
我愿意接受更好的选择,但这就是我解决它的方法:
console.clear();
let counter = 0;
const data = new Rx.BehaviorSubject(null);
function fetch() {
data.next(counter++);
}
function manualGet() {
console.log('manual');
fetch();
}
// setup poll
data.switchMap(() => Rx.Observable.timer(5000))
.subscribe(() => {
console.log('poll');
fetch();
});
// subscribe to the data
data.filter(x => x != null).
subscribe(x => { console.log('data', x); });
// do the first fetch
fetch();
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.5/Rx.min.js"></script>
<button onClick="manualGet()">Get Data</button>
使用ngrx,我正在侦听与fetch事件相关的成功操作。