rxjs观察阵列推送

时间:2017-02-10 22:49:49

标签: javascript arrays rxjs observable

我想监视何时使用observable将对象推送到数组上。我想从一个空数组开始,当发生推送时,我希望observable检测并处理它,然后等到下一次推送。这与" fromEvent"非常相似。 observable等待事件的地方。下面的代码立即调用completed(),因为数组是空的,如何让它等待推送?

    var testArray = [];

    test(){
      var o = {timestamp: new Date()}
      testArray.push(o)
    }

    var o = Observable
        .from(testArray)
        .concatMap( x => {
          return x;
    });

    o.subscribe( 
      x => { console.log("onNext x=",x.timestamp) },
      e => console.log('onError:', e),
      () => {console.log('onCompleted');} );

注意:输入机制不必是数组。任何类型的消息队列对象都适用于我。

3 个答案:

答案 0 :(得分:6)

如果您要做的就是创建一个可以推送的Observable'价值观,我建议使用RXJS主题。

const date$ = new Rx.Subject();
date$.next(new Date());

现在你有一个Observable Date对象流,你可以推送"使用next()方法。

如果您确实需要为队列提供中间(非可观察)数据类型,那么我建议使用新的ES6功能代理。

const queue = new Proxy([], {
  set: function(obj, prop, value) {
    if (!isNaN(prop)) {
      date$.next(value)
    }
    obj[prop] = value
    return true
  },
})

现在你有一个代理的数组,这样每当有一个值添加到它时,它就会被添加到你的Observable流中。

答案 1 :(得分:2)

你可以继承Array并实现某种通知机制来告诉你什么时候推送(这真的很简单):

class CustomArray extends Array {
  push(e) {
    super.push(e)
    if (this._listeners) {
      this._listeners.forEach(l => l(e))
    }
  }
  addPushListener(listener) {
    this._listeners = this._listeners || []
    this._listeners.push(listener)
  }
  removePushListener(listener) {
    if (this._listeners) {
      const index = this._listeners.indexOf(listener)
      if (index >= 0) {
        this._listeners.splice(index, 1)
      }
    }
  }
}

然后使用函数将其包装成Observable

const observePushes = array => Rx.Observable.fromEventPattern(
  array.addPushListener.bind(array),
  array.removePushListener.bind(array)
)

然后,您可以随时订阅更改和取消订阅,就像任何其他可观察的一样。

const arr = new CustomArray()
const pushObservable = observePushes(arr)

const subscription = pushObservable.subscribe(e => console.log(`Added ${e}`))

arr.push(1)
arr.push(2)
arr.push(3)
arr.push("a")

subscription.dispose()

arr.push("b")

还要注意这个Observable永远不会真正完成,因为在任何时候你都不能保证不再向数组添加任何内容。

小提琴:http://jsfiddle.net/u08daxdv/1/

答案 2 :(得分:-1)

如果你想模拟一些异步/延迟(很好的加载GIF!),你可以在你的服务类上做这样的事情:

constructor() {
  this.source =  new Subject<Array<any>>()
}

myObservableArray(): Observable<Array<any>> {
  setTimeout(() => {
    this.source.next([1, 2, 3])
  }, 3000)

  return this.source
}

..所以你以后可以做obj.myObservableArray().subscribe