Javascript 如何使用一个函数来映射一个可观察对象,该函数将其映射到一个值可观察的对象?

Javascript 如何使用一个函数来映射一个可观察对象,该函数将其映射到一个值可观察的对象?,javascript,rxjs,observable,Javascript,Rxjs,Observable,假设我有一个如下的函数: const mapObservableToObject = o$ => ({ counter: o$.pipe( pluck('values', 'counter') ) username: o$.pipe( pluck('user', 'username'), map(sanitizeUsername) ) input: unrelatedObservable$.pipe( pluck('target', 'v

假设我有一个如下的函数:

const mapObservableToObject = o$ => ({
  counter: o$.pipe(
    pluck('values', 'counter')
  )
  username: o$.pipe(
    pluck('user', 'username'),
    map(sanitizeUsername)
  )
  input: unrelatedObservable$.pipe(
    pluck('target', 'value'),
    distinct(),
    auditTime(300)
  )
})
我如何使用现有的可观察对象和这样的函数创建新的可观察对象?新的可观察对象应该发出
{counter,username,input}
形状的值,以及它们各自可观察对象的最新值,当它还没有收到值时,默认为
null
。(但可能是可选的默认设置?

试试看

const mapObservableToObject = o$ => ({
  counter: o$.pipe(
    pluck('values', 'counter'),
    startWith(null)
  )
  username: o$.pipe(
    pluck('user', 'username'),
    map(sanitizeUsername),
    startWith(null)
  )
  input: unrelatedObservable$.pipe(
    pluck('target', 'value'),
    distinct(),
    auditTime(300),
    startWith(null)
  )
})

const { counter, username, input } = mapObservableToObject(obs$);
combineLatest(counter, username, input).subscribe(v => console.log(v));

我正在使用这个自定义运算符,据我所知,它应该可以为您实现这一点,并且它与TypeScript的类型推断很好地配合:

  import { combineLatest, Observable } from 'rxjs';
  import { map } from 'rxjs/operators';

  /**
   * An equivalent of combineLatest, but using named arguments.
   */
  export const combineLatestToObject = <T>(
    source: { [P in keyof T]: Observable<T[P]> },
  ): Observable<{ [P in keyof T]: T[P] }> => {
    const keys = Object.keys(source);
    return combineLatest(keys.map(key => (source as any)[key])).pipe(
      map(values => {
        const result: { [key: string]: any } = {};
        for (const index in values) {
          result[keys[index]] = values[index];
        }
        return result;
      }),
    ) as any;
  };
从'rxjs'导入{combineLatest,Observable};
从“rxjs/operators”导入{map};
/**
*与CombineTest等效,但使用命名参数。
*/
导出常量CombineRelatestToObject=(
来源:{[P in keyof T]:可观测},
):可观察=>{
常量键=对象键(源);
返回CombineTest(key.map(key=>(source as any)[key])).pipe(
映射(值=>{
常量结果:{[key:string]:any}={};
for(常量索引值){
结果[键[索引]]=值[索引];
}
返回结果;
}),
)如有的话;
};
对于发出任何内容之前的默认值,您可以根据需要添加
startWith(null)
publishBehavior(null)
。还要注意在代码中订阅两次
o$
,如果
o$
是一个可以观察到的多播,但只是一个提示,那么这很好。

看一看