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

时间:2016-04-19 08:38:24

标签: javascript ecmascript-6 rxjs observable

我仍然在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方法计算了一堆observable,每个observable都会发出代表我的应用程序状态一部分的项。没关系。

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

2 个答案:

答案 0 :(得分:1)

我从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()

答案 1 :(得分:1)

使用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"
}