3

下面的代码片段是功能性的(从某种意义上说它正在工作;-)),但充其量似乎很蹩脚......

任何人都可以提出一种方法来使它更可组合或至少不那么难看吗?

代码基于此页面上的示例: 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);
  }
);
4

1 回答 1

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 视为“类固醇上的事件总线”而不是可链接 Promises 的替代品,因为它确实不是后者。

如果您将“应用程序中发生的一切”建模为事件流,则最好在 RxJS 上进行开发。如果做得好,你不应该看到这些可链接的“做这个,然后做那个,然后做那个”,因为最终这是一个命令式范式,而 RxJS 的能力不止于此。理想情况下,它应该更多地以声明的方式讲述事件是什么。有关更多解释,请参阅本教程,特别是“总结”部分中的论述。这个要点也可能有所帮助。

于 2014-08-15T13:16:52.147 回答