RxJs:仅在一段时间过后才有新价值

时间:2016-09-06 19:18:19

标签: javascript rxjs rxjs5 reactive-extensions-js

我是ReactiveExtensions的新手,我没有上班。我认为应该是一个非常常见的用例。我希望仅在特定时间段过后没有新的下一个值时才会收到新值。在底部示例中,这段时间是1秒。 debounce-operator似乎完全符合我的要求。我不能让它工作。

const observable$ = new Rx.Observable(observer => {

 observer.next('start');

 setTimeout(() => {
  observer.next(1);
 }, 100);
 setTimeout(() => {
  observer.next(2);
 }, 200);
 setTimeout(() => {
  observer.next(3);
 }, 300);
 setTimeout(() => {
  observer.next(4);
 }, 400);

 setTimeout(() => {
  observer.next('end');
 }, 1500);
});

let sub = observable$
      .debounce(1000) //debounce(1000, null) does not work either
      .take(100)
      .subscribe(data => {
          console.log(data);
         }, 
         err => console.log(err.message), 
         complete => console.log('Observable completed')
       )

我想得到的只是控制台输出:

"start"
"end"

在我的IDE(Webstorm)中,尽管文档声明第二个参数是可选的,但上面的代码甚至都没有编译。在jsbin.com我得到以下错误:“this.durationSelector.call不是函数”(我承认,我还不知道如何在rxjs中应用调度程序)。在文档中,他们也只使用了一个数字。我在谷歌上发现的大部分去抖动例子只使用一个数字,即example on Stackoverflow。为什么这不适用于我的情况?

感谢您的帮助!

PS:我使用的是rxjs 5.0.0-beta.6。

编辑:在这里的答案的帮助下,我找到了我想要的实际解决方案:

const observable$ = new Rx.Observable(observer => {

observer.next('start');

 setTimeout(() => {
  observer.next(1);
 }, 1100); //<-- If you change 1100 to i.e. 900 you just get "end" in the output, because there is no 1s periode during which no new value arrives. 
 setTimeout(() => {
  observer.next(2);
 }, 1200);
 setTimeout(() => {
  observer.next(3);
 }, 1300);
 setTimeout(() => {
  observer.next(4);
 }, 1400);
 setTimeout(() => {
  observer.next(5);
 }, 1500);

 setTimeout(() => {
  observer.next('end');
 }, 1501);


});

let sub = observable$
      .debounceTime(1000)
      .take(10)
      .subscribe(data => {
         console.log(data);
       }, 
       err => console.log(err.message), 
       complete => console.log('Observable completed')
);

2 个答案:

答案 0 :(得分:3)

这仅仅是旧版RxJS的文档问题。 RxJS 4重载debounce here

然而,RxJS 5拆分运算符,实际上有两个,一个使用选择器函数来确定去抖长度,另一个debounceTime接受一个时间。

因此您的信息流成为:

let sub = observable$
      .debounceTime(1000) //debounce(1000, null) does not work either
      .take(100)
      .subscribe(data => {
          console.log(data);
         }, 
         err => console.log(err.message), 
         complete => console.log('Observable completed')
       )

答案 1 :(得分:2)

你可以做这样的事情

const observable$ = new Rx.Observable(observer => {

    observer.next('start');

    setTimeout(() => {
        observer.next(1);
    }, 100);
    setTimeout(() => {
        observer.next(2);
    }, 200);
    setTimeout(() => {
        observer.next(3);
    }, 300);
    setTimeout(() => {
        observer.next(4);
    }, 400);

    setTimeout(() => {
        observer.next('end');
    }, 1500);


});

let sub = observable$
    .map(function(x, i) {
        return {
            val: x,
            index: i
        };
    })
    .debounce(function(obj) {
        let interval = obj.index === 0 ? 0 : 1500;
        return Rx.Observable.timer(interval);
    })
    .take(100)
    .subscribe(data => {
            console.log(data.val);
        },
        err => console.log(err.message),
        complete => console.log('Observable completed')
    )

这里的关键是使用map函数来获取元素的索引,然后决定等待间隔。