[英]RxJS: How to combine multiple nested observables with buffer
警告:RxJS newb在這里。
這是我的挑戰:
onUnlink$
observable發出... onAdd$
observable捕獲值,最多1秒鍾(我將這個分區onAddBuffer$
)。 doc$
observable)以獲取我們將用於匹配其中一個onAdd$
值的模型 onAddBuffer$
observable中的一個值與doc$
值匹配,請不要發出 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.