Ove*_*d D 4 reactive-programming rxjs
我希望能够从外部Api获取特定请求的数据,但是当返回该数据时,也使其在缓存中可用,以表示应用程序的当前状态.
这个解决方案似乎有效:
var Rx = require('rx');
var cached_todos = new Rx.ReplaySubject(1);
var api = {
refresh_and_get_todos: function() {
var fetch_todos = Rx.Observable.fromCallback($.get('example.com/todos'));
return fetch_todos()
.tap(todos => cached_todos.onNext(todos));
},
current_todos: function() {
return cached_todos;
}
};
Run Code Online (Sandbox Code Playgroud)
但是 - 显然Subjects在Rx中是不好的做法,因为它们并不真正遵循功能性反应式编程.
以功能性反应式编程方式执行此操作的正确方法是什么?
建议不要使用,Subjects因为有一种倾向滥用它们来注射副作用.它们完全有效,可以用作将值推送到流中的方法,但是它们的范围应该严格限制,以避免出血状态进入其他代码区域.
这是第一次重构,请注意您可以事先创建源代码,然后您的api代码只是将它包裹在一个整洁的小弓中:
var api = (function() {
var fetch_todos = Rx.Observable.fromCallback($.get('example.com/todos'))
source = new Rx.Subject(),
cached_todos = source
.flatMapLatest(function() {
return fetch_todos();
})
.replay(null, 1)
.refCount();
return {
refresh: function() {
source.onNext(null);
},
current_todos: function() {
return cached_todos;
}
};
})();
Run Code Online (Sandbox Code Playgroud)
以上是好的,它保持你当前的界面和副作用和状态已被包含,但我们可以做得更好.我们可以创建一个扩展方法或一个接受一个的静态方法Observable.然后,我们可以进一步简化为:
//Executes the function and caches the last result every time source emits
Rx.Observable.withCache = function(fn, count) {
return this.flatMapLatest(function() {
return fn();
})
.replay(null, count || 1)
.refCount();
};
//Later we would use it like so:
var todos = Rx.Observable.fromEvent(/*Button click or whatever*/))
.withCache(
Rx.Observable.fromCallback($.get('example.com/todos')),
1 /*Cache size*/);
todos.subscribe(/*Update state*/);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2208 次 |
| 最近记录: |