简体   繁体   English

RXJS 扫描 - withLatestFrom another observable

[英]RXJS Scan - withLatestFrom another observable

I'm trying to work out how to use scan to derive a new state whenever my input observable emits a new value, but I can't seem to get it working.当我的输入 observable 发出新值时,我正在尝试解决如何使用 scan 来派生新状态,但我似乎无法让它工作。

I want to output a new State every time the input$ observable emits a new value, but it should be derived from the current value of state$.每次 input$ observable 发出新值时,我都想输出一个新状态,但它应该从 state$ 的当前值派生。

Can anyone suggest how I can fix this?谁能建议我如何解决这个问题? I have a feeling I've got the wrong idea altogether :-)我有一种感觉,我完全有错误的想法:-)

My code looks something like this:我的代码看起来像这样:

const stateReducer = (state$: Observable<State>, input$: Observable<Input>) => {
  state$ = state$.pipe( startWith(DEFAULT_STATE) );

  const foo$: Observable<State> = input$.pipe(
    filter((input) => isFoo(input)),
    withLatestFrom(state$),
    scan((acc, ([input, state]) => {
        //returns derived state
    });

   const bar$: Observable<State> = input$.pipe(
    filter((input) => isBar(input)),
    withLatestFrom(state$),
    scan((acc, ([input, state]) => {
        //returns derived state
    });

   return merge(
     foo$,
     bar$
   );
}

Since you want to use the result of an Observable as your seed value, switchMap will help.由于您想使用 Observable 的结果作为种子值, switchMap会有所帮助。

switchMap docs switchMap 文档

   const bar$: Observable<State> = state$.pipe(
    switchMap((state) => {
      return input$.pipe(
        filter((input) => isBar(input)),  
        scan((curState, input) => {
          // do some logic here
          return {...curState, prop: 'new value'}
        }, state);
      )
    })

I've made a sample CodePen for a more complete solution at https://codepen.io/askmattcairns/pen/LYjEoZz?editors=0010 .我在https://codepen.io/askmattcairns/pen/LYjEoZz?editors=0010制作了一个示例 CodePen 以获得更完整的解决方案。


More Details更多细节

switchMap means to switch to the stream in here. switchMap意思是切换到这里的流。 So this code is saying, once state$ emits a value, store it (as state ), then wait for input$ to emit.所以这段代码是说,一旦state$发出一个值,将它存储(作为state ),然后等待input$发出。

When we call scan , its seed value (the second property of scan ) is now the result of state$ 's emitted value.当我们调用scan ,它的种子值( scan的第二个属性)现在是state$的发射值的结果。

This will emit a new value any time input$ receives a new value.这将在input$收到新值时发出新值。

Update to Code Sandbox代码沙盒更新

After digging in to your Code Sandbox, I better understand what the problem is.在深入了解您的代码沙箱后,我更好地了解了问题所在。 You can see my final output at https://codesandbox.io/s/elegant-chaum-2b794?file=/src/index.tsx .你可以在https://codesandbox.io/s/elegant-chaum-2b794?file=/src/index.tsx看到我的最终输出。

When you initialize your 2 inner streams foo$ and bar$ , they both reference state$ using withLatestFrom .当您初始化 2 个内部流foo$bar$ ,它们都使用withLatestFrom引用state$ Each time input$ emits, it still references the original value of state , using 0 as its starting total.每次input$发出时,它仍然引用state的原始值,使用 0 作为其起始总数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM