从Observable列表中创建一个Observable对象

Create an Observable object from a list of Observables

本文关键字:Observable 对象 一个 列表 创建      更新时间:2023-09-26

我仍在思考RxJS,我一直在遇到这种模式,我想找到一种更优雅的写作方式。

在实现model View Intent模式组件的模型部分时,我有一个函数,它将操作作为输入,并返回单个state$ Observable作为输出。

function model(actions) {
    const firstProperty$ = 
    const anotherProperty$ = …
    // Better way to write this?
    const state$ = Rx.Observable.combineLatest(
        firstProperty$, anotherProperty$,
        (firstProperty, anotherProperty) => ({
            firstProperty, anotherProperty
        })
    );
    return state$;
}

因此,我的model方法计算了一组可观测值,其中每一个都会发出表示我的应用程序状态的一部分的项。那很好。

但是,我如何将它们干净地组合成一个可观察的、发出状态的对象,每个状态都是一个对象,其键是初始可观察的名称?

我借用了https://github.com/cyclejs/todomvc-cycle:

function model(initialState$, actions){
  const mod$ = modifications(actions)
  return initialState$
  .concat(mod$)
  .scan( (state, mod) => mod(state))
  .share() 
}
function modifications(actions){
  const firstMod$ = actions.anAction$.map(anAction => (
    state => ({ ...state,
      firstProperty: anAction.something
    })
  const secondMod$ = actions.otherAction$.map(otherAction => (
    state => ({ ...state,
      firstProperty: otherAction.something,
      secondProperty: aComputation(otherAction)
    })
  return Rx.Observable.merge([firstMod$, secondMod$ ]).share()
}

在主要功能:

const initialState$ = Rx.Observable.from({})
const actions = intent(DOM)
const state$ = model(initialState$, actions).share()

使用CHadrien的帮助,这里有一个有效的解决方案。

const prop1$ = Rx.Observable.of('foo');
const prop2$ = Rx.Observable.of('bar');
const prop3$ = Rx.Observable.of('baz');
const prop4$ = Rx.Observable.of('foobar');
function combineObservables(objectOfObservables) {
  const keys = Object.keys(objectOfObservables);
  const observables = keys.map(key => objectOfObservables[key]);
  const combined$ = Rx.Observable.combineLatest(
    observables, (...values) => {
      var obj = {};
      for (let i = 0 ; i < keys.length ; i++) {
        obj[keys[i]] = values[i];
      }
      return obj;
    }
  );
  return combined$;
}
combineObservables({prop1$, prop2$, prop3$, prop4$}).subscribe(x => console.log(x));

结果:

[object Object] {
  prop1$: "foo",
  prop2$: "bar",
  prop3$: "baz",
  prop4$: "foobar"
}