将两个回调折叠到一个Observable中

时间:2014-08-15 11:20:01

标签: mongodb rxjs

以下代码片段功能正常(从某种意义上来说它正在运行;-)),但最好也很蹩脚......

任何人都可以建议一种方法,使其更易于组合或至少不那么丑陋吗?

代码基于此页面上的示例: Wrap an Existing API with RxJS

function connect() {
  return rx.Observable.create(function (observer) {
    mongo.connect('mongodb://127.0.1:27017/things', function(err, db) {
      if(err) observer.onError(err);
      observer.onNext(db);
    });
  }).publish().refCount();
}

function getThings(db) {
  return rx.Observable.create(function (observer) {
    db.collection('things').find().toArray(function(err, results) {
      if(err) observer.onError(err);
      observer.onNext(results);
      observer.onCompleted();
    });
    return function () {
      db.close();
    };
  }).publish().refCount();
}


connect().subscribe(
  function (db) {
    getThings(db).subscribe(console.log);
  }, function (err) {
    console.log(err);
  }
);

1 个答案:

答案 0 :(得分:5)

在这个具体示例中,假设getThings()应该在connect()发生后仅发生一次,我会改变getThings()的实现:

function getThings() {
  return connect()
    .flatMap(function(db) {
      return rx.Observable.create(function (observer) {
        db.collection('things').find().toArray(function(err, results) {
          if(err) observer.onError(err);
          observer.onNext(results);
          observer.onCompleted();
        });
        return function () {
          db.close();
        };
      });
    });
}

然后您可以订阅getThings()流:

getThings().subscribe(console.log);

我们使用flatMap隐藏整个getThings()内的连接步骤。 FlatMap的文档听起来很复杂,但并不复杂。它只是将源Observable中的事件替换为另一个未来事件。在图表中进行了解释,它将每个x事件替换为将来的y事件。

---x----------x------->
flatMap( x => --y--> )
------y----------y---->

在我们的案例中,x事件已成功连接"并且y已经"得到了'事情'来自数据库"。


也就是说,根据应用程序的工作方式,有几种不同的方法可以实现。最好将RxJS视为"类固醇上的事件总线"而不是可链接Promise的替代品,因为它实际上不是后者。

如果您对应用程序中发生的一切进行建模,那么在RxJS上进行开发是最好的。作为事件的流。如果做得恰当,你不应该看到这些可链接的"做到这一点,然后这样做,然后做那个",因为最终这是一个必要的范例,而RxJS能够做到这一点。理想情况下,它应该更多地以声明的方式告诉事件是什么。有关更多解释,请参阅this tutorial,特别是"结束"部分。此gist也可能会有所帮助。