Javascript RxJs:获取哪些对象键按顺序更改,并通过distinctUntilChanged()过滤,而不保留外部状态

Javascript RxJs:获取哪些对象键按顺序更改,并通过distinctUntilChanged()过滤,而不保留外部状态,javascript,typescript,rxjs,observable,Javascript,Typescript,Rxjs,Observable,Letorders$是对象的RxJs序列,如下所示。我们使用distinctUntilChanged()监听更改,并根据更改的键采取不同的操作。我们是否可以在tap()内部判断实际更改了哪个对象键,而不通过外部{ /*哪个值实际发生了变化-‘main’或‘drink’*/ if(previousItem&&previousItem.main!==item.main){ dosthForminChanged(); } doSthForDrinkChanged(); previousItem=ite

Let
orders$
是对象的RxJs序列,如下所示。我们使用
distinctUntilChanged()
监听更改,并根据更改的键采取不同的操作。我们是否可以在
tap()
内部判断实际更改了哪个对象键,而不通过外部
变量跟踪以前的更改

例如:

let orders$ = of([
  { main: 'pizza', drink: 'cola', id: 0},
  { main: 'pizza', drink: 'cola', id: 1},
    ...
  { main: 'pizza', drink: 'cola', id: 3332},
  { main: 'pizza', drink: 'fanta', id: 3333},    // <-- drink changes
]); 

let previousItem = null;

orders$.pipe(
  distinctUntilChanged((o0, o1) => o0.main === o1.main || o0.drink === o1.drink),
  tap(item => {

      /* Which value actually changed -'main' or 'drink' ?! */

      if (previousItem && previousItem.main !== item.main) {
        doSthForMainChanged();
      }

      doSthForDrinkChanged();
      previousItem = item;        // <-- ... so that not to tweak via external state

  })).subscribe();
let orders$=of([
{main:'pizza',drink:'cola',id:0},
{主菜:'比萨饼',饮料:'可乐',id:1},
...
{main:'pizza',drink:'cola',id:3332},
{main:'pizza',drink:'fanta',id:3333},//o0.main==o1.main | | o0.drink==o1.drink),
点击(项目=>{
/*哪个值实际发生了变化-‘main’或‘drink’*/
if(previousItem&&previousItem.main!==item.main){
dosthForminChanged();
}
doSthForDrinkChanged();

previousItem=item;//对于每种类型的更改,您可以将可观察到的内容分成两个流,然后使用map跟踪这些更改

   const main$ = orders$.pipe(
        distinctUntilChanged((o0, o1) => o0.main === o1.main),
        map(value => ({changed:'main', value}))
   );

   const drink$ = orders$.pipe(
        distinctUntilChanged((o0, o1) => o0.drink === o1.drink),
        map(value => ({changed:'drink', value}))
   );

   merge(main$, drink$).pipe(
       tap(item => {
          if (item.changed === 'main') {
              doSthForMainChanged();
          } else if(item.changed === 'drink') {
              doSthForDrinkChanged();
          }
   })).subscribe();

上述操作的唯一副作用是,如果一个排放值的主水和饮料都发生变化,则tap将执行两次。我不知道这是否是您的业务逻辑的问题。

我可以建议使用
扫描

source$.pipe(
  scan((last: any, item: any) => {
    let changes: any = {}
    last.main !== item.main ? changes.main = true : false
    last.drink !== item.drink ? changes.drink = true : false
    return {item, changes}
  }, {}),
  tap(({item, changes}) => {
    if (changes.main) {
      doSthForMainChanged();
    }
    if (changes.drink) {
      doSthForDrinkChanged();
    }    
  })
)

如果需要,您还可以在末尾添加distinctUntilChanged

是否尝试了成对运算符[?