2017-07-07 65 views
1

我是RxJS的新手,试图做一个简单的演示,让您每隔一秒刷新一次数据。RxJS:点击后禁用刷新按钮持续时间

我做了一个按钮,并从中创建了一个点击流。 这个问题开始时,我想创建一个流,每个按钮点击发出错误,并在一秒钟后再次发出真实。

例如 - 初始状态为真,因为我们可以在开始时刷新。 一旦我点击按钮,新值应该是错误的点击后,因为我们不能进一步刷新。

最后一秒钟过后 - 值应该再次为真。

我试图创建它并成功,但它看起来很糟糕。 任何想法热点做得更好,更清洁? 另一件事是我真的不知道在这里使用RxJS是一个好主意,因为简单的常规方法是将布尔值设置为true,并在单击后将其设置为false,并使用setTimeout将其更改为true 。

这里是我做的:

// 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

处理异步操作与rxjs是一个很好的主意。这就是反应式编程的意义所在,而rxjs擅长这样做。

您生成的代码之美就是它是纯粹的。它不依赖于任何外部环境。

使用setTimeout和良好的布尔值来改变状态当然会工作,但以纯度和函数式编程为代价。你会做命令性的编程和副作用。和代码的语义不相同

button.addEventListener("click", function refresh(event) { 
    refreshData(); 
    setTimeout(renderButton, 1000, true) 
    renderButton(false) 
}) 

的用这段代码的问题:这是非常依赖于它的上下文。为了它的工作,你需要实现refreshDatarenderButton。他们也需要从该范围访问。

但是你的一段代码是完全独立的,你可以在别处复制/粘贴,它仍然可以工作。

的另一个问题是,点击事件处理函数负责太多的东西(其实刷新数据,渲染按钮的新状态,并启动超时。这是完全打破了单一职责原则

我希望我已经帮你看到你已经生成的代码的好处。它实际上是相当不错的,它只是习惯了的事情。

一个简单的简化你可以把会使用startWithmapTo代替的那种哈克!!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); 
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);