我是RxJS的新手并尝试做一个简单的演示,让你每隔一秒刷新一次数据。
我创建了一个按钮并从中创建了一个点击流。 问题开始时,我想创建一个流,每个按钮单击发出错误,并在一秒后再次发出true。
例如 - 初始状态为true,因为我们可以在开始时刷新。 一旦我点击按钮,新点值应该在点击后立即为假,因为我们无法进一步刷新。
最后一秒钟过后 - 该值应该再次为真。
我尝试创造并成功,但看起来很糟糕。 有什么想法可以做得更好更干净吗? 另一件事是我真的不知道在这里使用RxJS是否是一个好主意,因为简单的常规方法是将布尔值设置为true,然后在我点击后将其设置为false并使用setTimeout将其更改回真。
这就是我所做的:
// The stream of the button clicks.
$clicksStream
// Change the click stream to the timed true false change.
.switchMap(() => Observable
// Emit first value immediately and every 1 second after.
.timer(0, 1000)
// Map each one - 0 becomes false and others true.
.map(x => !!x)
// Take only first two items.
.take(2))
// Always the start value is true.
.startWith(true);
答案 0 :(得分:0)
使用rxjs
处理异步操作是一个很好的主意。反应式编程是关于什么的,rxjs
擅长这样做。
你所产生的代码的美妙之处在于它是纯粹的。它并不依赖于任何外部环境。
使用setTimeout
和好的'布尔改变状态当然会起作用,但代价是纯度和函数式编程。你会做命令式编程和副作用。并且代码的语义不会相同
button.addEventListener("click", function refresh(event) {
refreshData();
setTimeout(renderButton, 1000, true)
renderButton(false)
})
这段代码的问题:它非常依赖于它的上下文。要使其发挥作用,您需要实施refreshData
和renderButton
。他们还需要从该范围访问。
但是你的代码完全是独立的,你可以将它复制/粘贴到其他地方,它仍然有用。
另一个问题是点击处理函数负责太多事情(实际刷新数据,呈现按钮的新状态并启动超时。它完全打破单一责任原理强>
我希望我已经帮助您了解您所生成代码的好处。它实际上非常好,它只是习惯它的问题。
您可以使用startWith
和mapTo
而不是hacky !!x
进行简单的简化:)
$clicksStream
// Change the click stream to the timed true false change.
.switchMap(() => Observable
// just a timer of 1000ms
.timer(1000)
// when it emits we just return true
.mapTo(true)
// Take only first two items.
.startWith(false)
)
// Always the start value is true.
.startWith(true);
答案 1 :(得分:0)
您可以使用timeoutWith
运算符执行此操作。
$clickStream
.switchMapTo(
// Start with false
Observable.of(false)
// If no values are emitted for 1 second emit true
.timeoutWith(1000, Observable.of(true))
)
.startWith(true);