以下代码片段功能正常(从某种意义上来说它正在运行;-)),但最好也很蹩脚......
任何人都可以建议一种方法,使其更易于组合或至少不那么丑陋吗?
代码基于此页面上的示例: 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);
}
);
答案 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也可能会有所帮助。