Node.js 如何使用rxjs处理序列观测值?

Node.js 如何使用rxjs处理序列观测值?,node.js,rxjs,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 Observab

我有下一个场景:

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))
因为我正在为NodeJ使用MongoDB驱动程序,所以我需要使用
.fromPromise
,这样我就可以将它“转换”到
可观察的

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

我认为您可以使用
zip
CombineTest
来完成上述任务

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);
});

或其他类似的方式,但顺序如下:

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));

好奇的是,你能把这两个
findOne
组合成一个查询(有这个用户名或者有这个电子邮件)或者并行运行它们吗?另外,我会假设在最后一个
map
之后还有其他操作符,因为如果你不
订阅
,它就不会通过
this.players.findOne({username:username})
promise。我认为代码很好,如果你想同时检查用户名和电子邮件,你可以使用merge()在任何数据返回的情况下,您都可以返回错误。需要一个错误捕捉器吗too@Tr1et是的,我订阅了另一个函数,这个函数只返回可观察的。然而,我想合并成单个
findOne
,但我需要知道用户名或电子邮件不是唯一的,这样我才能向用户显示适当的消息。@Fanchuen这看起来是一个不错的建议,我将尝试合并,也许代码看起来会更漂亮:D