如何使用rxjs处理序列可观察量?

时间:2018-01-07 23:42:08

标签: node.js rxjs

我有下一个场景:

if (username exists in database)
    throw new Error(msg1);
if (email exists in database)
    throw new Error(msg2);
insertNewPlayer(username, email, password);

我的环境是带有TypeScript的nodejs,我正在为nodejs使用RxJS和MongoDB驱动程序。我写了下一段代码:

return Observable.fromPromise(this.players.findOne({username: username}))
    .mergeMap(data => {
        if(data) throw new Error("That username is taken!");
        return Observable.fromPromise(this.players.findOne({email: email}));
    })
    .mergeMap(data => {
        if(data) throw new Error("That email is taken!");
        return Observable.fromPromise(this.players.insert(playerData));
    })
    .map(result => this.createNewPlayerFromData(playerData))

由于我使用MongoDB驱动程序作为nodejs,我需要使用.fromPromise所以我可以"施放"它到Observable ...

这是正确的方法吗?或者还有其他方法吗? (不要担心createNewPlayerFromData函数,它只是将playerData对象转换为Player类型的对象

2 个答案:

答案 0 :(得分:1)

或者其他类似的方式,但按顺序排列:

const username$ = Observable
  .fromPromise(this.players.findOne({username: username}))
  .switchMap(x => x ? of(x) : _throw('That username is taken.'));

const email$ = Observable
  .fromPromise(this.players.findOne({email: email}))
  .switchMap(x => x ? of(x) : _throw('That email is taken.'));

const insertData = (data) => Observable
  .fromPromise(this.players.insert(playerData));

const insertPlayer$ = Observable.zip(
  username$, email$, (username, email) => ({ username, email }))
  .switchMap(data => insertData(data));

insertPlayer$.subscribe(x => this.createNewPlayerFromData(x));

答案 1 :(得分:0)

我认为您可以使用zipcombineLatest来完成上述任务。

const username$ = Observable
  .fromPromise(this.players.findOne({username: username}));

const email$ = Observable
  .fromPromise(this.players.findOne({email: email}));

const insertData = (data) => Observable
  .fromPromise(this.players.insert(data));

Observable.zip(username$, email$, (username, email) => {
  if (!username) {
    throw new Error('That username is taken!');
  }

  if (!email) {
    throw new Error('That email is taken!');
  }

  return { username, email };
})
  .switchMap(data => insertData(data))
  .subscribe(x => {
     this.createNewPlayerFromData(x);
});