Javascript 如何在某些可观测数据中使用组合测试和过滤器?

Javascript 如何在某些可观测数据中使用组合测试和过滤器?,javascript,rxjs,pipeline,redux-observable,combinelatest,Javascript,Rxjs,Pipeline,Redux Observable,Combinelatest,这是一个复杂情况的简化,在这种情况下,如果值无效,可以过滤阵列中的一些观察值。问题是,过滤后的可观察对象不允许另一个完成联合收割机。什么操作员或方法可以处理这种情况,允许订阅中的有效数据日志 // RxJS v6+ import { fromEvent, combineLatest, of } from 'rxjs'; import { mapTo, startWith, scan, tap, map, filter } from 'rxjs/operators'; const userDat

这是一个复杂情况的简化,在这种情况下,如果值无效,可以过滤阵列中的一些观察值。问题是,过滤后的可观察对象不允许另一个完成联合收割机。什么操作员或方法可以处理这种情况,允许订阅中的有效数据日志

// RxJS v6+
import { fromEvent, combineLatest, of } from 'rxjs';
import { mapTo, startWith, scan, tap, map, filter } from 'rxjs/operators';

const userData$ = [
   of({ name: 'Joseph', age: 23}), 
   of({ name: 'Mario', age: 33}), 
   of({ name: 'Robert', age: 24}), 
   of({ name: 'Alonso', age: 25})
];

const names = ['Joseph', 'Mario', 'Robert', 'Alonso'];

combineLatest(
  names.map((name, i) => {
     return userData$[i].pipe(
         map(({name, age})=> { return{ name, age: age * 2} }),
         filter(({age}) => age < 67),
         map(({name, age})=> { return{ name: name.toLocaleUpperCase(), age} }),
     )
 })
)
   .pipe(
     tap(console.log),
   )
   .subscribe();
//rxjsv6+
从“rxjs”导入{fromEvent,CombineTest,of};
从“rxjs/operators”导入{mapTo、startWith、scan、tap、map、filter};
const userData$=[
({姓名:'Joseph',年龄:23}),
({姓名:'Mario',年龄:33}),
({姓名:'Robert',年龄:24}),
({姓名:阿隆索,年龄:25})
];
常量名称=['Joseph','Mario','Robert','Alonso'];
组合测试(
names.map((name,i)=>{
返回userData$[i]。管道(
map({name,age})=>{return{name,age:age*2}),
过滤器({age}=>age<67),
map({name,age})=>{return{name:name.tolocalueppercase(),age}),
)
})
)
.烟斗(
点击(console.log),
)
.subscribe();


如果我们将该值更改为67,则所有可观测值都将显示数据。

您可以将
combinelateest
替换为
from
,因为如果流数组中的任何一项不发射,则
combinelateest
将不发射

const userData$ = [
  { name: 'Joseph', age: 23 },
  { name: 'Mario', age: 33 },
  { name: 'Robert', age: 24 },
  { name: 'Alonso', age: 25 }
];

const names = ['Joseph', 'Mario', 'Robert', 'Alonso'];

from(
  userData$
)
  .pipe(
    map(({ name, age }) => { return { name, age: age * 2 } }),
    filter(({ age }) => age < 66),
    map(({ name, age }) => { return { name: name.toLocaleUpperCase(), age } }),
    tap(console.log),
  )
  .subscribe();
const userData$=[
{姓名:'Joseph',年龄:23},
{姓名:'马里奥',年龄:33},
{姓名:'Robert',年龄:24},
{姓名:“阿隆索”,年龄:25}
];
常量名称=['Joseph','Mario','Robert','Alonso'];
从(
用户数据$
)
.烟斗(
map({name,age})=>{return{name,age:age*2}),
过滤器({age}=>age<66),
map({name,age})=>{return{name:name.tolocalueppercase(),age}),
点击(console.log),
)
.subscribe();

组合相关测试的一个典型问题是,它要求所有源观测值至少发射一次,因此如果使用
过滤器
丢弃其唯一值,那么
组合相关测试
将永远不会发射任何东西

一个简单的解决方案是确保它总是发出
defaultIfEmpty

combineLatest(
  names.map((name, i) => {
    return userData$[i].pipe(
      map(({name, age})=> { return { name, age: age * 2} }),
      filter(({age}) => age < 66),
      map(({name, age})=> { return { name: name.toLocaleUpperCase(), age} }),
      defaultIfEmpty(null),
    )
  })
)
组合测试(
names.map((name,i)=>{
返回userData$[i]。管道(
map({name,age})=>{return{name,age:age*2}),
过滤器({age}=>age<66),
map({name,age})=>{return{name:name.tolocalueppercase(),age}),
defaultIfEmpty(null),
)
})
)
现场演示:

如果您的实际用例使用的不是()的
of
的其他可观察的源代码不能立即完成,那么您可能需要使用
startWith