簡體   English   中英

RxJS:如何將多個嵌套的observable與緩沖區組合在一起

[英]RxJS: How to combine multiple nested observables with buffer

警告:RxJS newb在這里。

這是我的挑戰:

  1. 當一個onUnlink$ observable發出...
  2. 立即開始從onAdd$ observable捕獲值,最多1秒鍾(我將這個分區onAddBuffer$ )。
  3. 查詢數據庫(創建doc$ observable)以獲取我們將用於匹配其中一個onAdd$值的模型
  4. 如果onAddBuffer$ observable中的一個值與doc$值匹配,請不要發出
  5. 如果onAddBuffer$ observable中的值都不匹配doc$值,或者onAddBuffer$ observable從未發出,則發出doc$

這是我最好的猜測:

// for starters, concatMap doesn't seem right -- I want a whole new stream
const docsToRemove$ = onUnlink$.concatMap( unlinkValue => {

  const doc$ = Rx.Observable.fromPromise( db.File.findOne({ unlinkValue }) )

  const onAddBuffer$ = onAdd$
    .buffer( doc$ ) // capture events while fetching from db -- not sure about this
    .takeUntil( Rx.Observable.timer(1000) );

  // if there is a match, emit nothing. otherwise wait 1 second and emit doc
  return doc$.switchMap( doc =>
    Rx.Observable.race( 
      onAddBuffer$.single( added => doc.attr === added.attr ).mapTo( Rx.Observable.empty() ),
      Rx.Observable.timer( 1000 ).mapTo( doc )
    )
  );
});

docsToRemove$.subscribe( doc => {
  // should only ever be invoked (with doc -- the doc$ value) 1 second
  // after `onUnlink$` emits, when there are no matching `onAdd$`
  // values within that 1 second window.
})

這總是會發出EmptyObservable 也許這是因為當沒有匹配時, single似乎發出undefined ,並且我期望在沒有匹配時它根本不發出? find

如果我將single更改為filter ,則不會發出任何內容。

僅供參考:這是具有文件系統事件的重命名方案 - 如果在unlink事件的1秒內發生add事件並且發出的文件哈希匹配,則不執行任何操作,因為它是rename 否則它是一個真正的unlink ,它應該發出要刪除的數據庫doc。

這是我猜你怎么做到這一點:

onUnlink$.concatMap(unlinkValue => {
  const doc$ = Rx.Observable.fromPromise(db.File.findOne({ unlinkValue })).share();
  const bufferDuration$ = Rx.Observable.race(Rx.Observable.timer(1000), doc$);
  const onAddBuffer$ = onAdd$.buffer(bufferDuration$);

  return Observable.forkJoin(onAddBuffer$, doc$)
    .map(([buffer, docResponse]) => { /* whatever logic you need here */ });
});

single()運算符有點棘手,因為它只在源Observable完成后才發出與謂詞函數匹配的項(或者在有兩個項或沒有匹配項時發出錯誤)。

race()很棘手。 如果其中一個源Observable完成並且沒有發出任何值,則race() 將完成並且不會發出任何內容 我前段時間報告了這一點,這是正確的行為,請參閱https://github.com/ReactiveX/rxjs/issues/2641
我猜你的代碼出了問題。

另請注意, .mapTo(Rx.Observable.empty())會將每個值映射到Observable的實例中。 如果要忽略所有值,可以使用filter(() => false)ignoreElements()運算符。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM