rxjs 在订阅时只使用一次承诺
rxjs using promise only once on subscribe
我想第一次使用 rxjs
但有点卡住了,因为它的行为与我想要的不完全一样:在我的场景中,我想从承诺中创建一个可观察对象。但我希望承诺只被调用一次(不是在每个订阅上)并且我希望它不在创建时被调用(将调用推迟到第一个订阅)。
首先我尝试了这个:
var source = Rx.Observable.fromPromise(_this.getMyPromise())
这导致在创建时立即调用 getMyPromise
函数。这个不太满意,因为那个时候不知道源码是不是真的会用
然后我尝试了:
var source = Rx.Observable.defer(function() { return _this.getMyPromise() })
每次对源进行新订阅时都会调用 getMyPromise
函数。这对网络服务器造成了太多不必要的调用。 Rx.Observable.create
函数似乎有同样的问题。
那么我还剩下什么或缺少什么?
.shareReplay()
这样做,例如:
var source = Rx.Observable.defer(function() { return _this.getMyPromise() }).shareReplay();
如果您使用的是 rxjs5,您需要阅读:
在回答您在下面的评论时,我可以想到对上述逻辑进行相当简单的扩展,它可以满足您的要求,但有一个警告。假设您想用来触发 "refresh" 的事件在流 s$ 中表示,那么您可以执行以下操作:
var source = Rx.Observable.of({}).concat(s$)
.flatMapLatest(function() {
return Rx.Observable.defer(function() {
return _this.getMyPromise()
})
})
.shareReplay(1)
我们这里有一个流,以一个虚拟对象开始,让事情滚动,然后是一个由您的刷新事件组成的流。这些中的每一个都被投影到一个新的可观察对象中,该观察对象是通过重新调用您的 getMyPromise 方法创建的,并且整个事情被扁平化为一个单一的流。最后,我们保留了 shareReplay 逻辑,所以我们只在应该调用的时候才实际调用。
需要注意的是,这只有在始终至少有一个订阅者订阅源的情况下才能正常工作(处理所有其他订阅者后的第一个订阅者将再次 运行 承诺,并将收到之前的两个 -缓存值及其对 运行).
的承诺结果
这里有一个答案,它不需要使用简单的帮助程序始终在源头至少有一个订阅者:
var _p = null;
var once = function() { return _p || (_p = _this.getMyPromise());
var source = Rx.Observable.defer(once);
或者,如果您使用的是 lodash,您可以 _.memoize
您的 getMyPromise
并自动获取它。
我想第一次使用 rxjs
但有点卡住了,因为它的行为与我想要的不完全一样:在我的场景中,我想从承诺中创建一个可观察对象。但我希望承诺只被调用一次(不是在每个订阅上)并且我希望它不在创建时被调用(将调用推迟到第一个订阅)。
首先我尝试了这个:
var source = Rx.Observable.fromPromise(_this.getMyPromise())
这导致在创建时立即调用 getMyPromise
函数。这个不太满意,因为那个时候不知道源码是不是真的会用
然后我尝试了:
var source = Rx.Observable.defer(function() { return _this.getMyPromise() })
每次对源进行新订阅时都会调用 getMyPromise
函数。这对网络服务器造成了太多不必要的调用。 Rx.Observable.create
函数似乎有同样的问题。
那么我还剩下什么或缺少什么?
.shareReplay()
这样做,例如:
var source = Rx.Observable.defer(function() { return _this.getMyPromise() }).shareReplay();
如果您使用的是 rxjs5,您需要阅读:
在回答您在下面的评论时,我可以想到对上述逻辑进行相当简单的扩展,它可以满足您的要求,但有一个警告。假设您想用来触发 "refresh" 的事件在流 s$ 中表示,那么您可以执行以下操作:
var source = Rx.Observable.of({}).concat(s$)
.flatMapLatest(function() {
return Rx.Observable.defer(function() {
return _this.getMyPromise()
})
})
.shareReplay(1)
我们这里有一个流,以一个虚拟对象开始,让事情滚动,然后是一个由您的刷新事件组成的流。这些中的每一个都被投影到一个新的可观察对象中,该观察对象是通过重新调用您的 getMyPromise 方法创建的,并且整个事情被扁平化为一个单一的流。最后,我们保留了 shareReplay 逻辑,所以我们只在应该调用的时候才实际调用。
需要注意的是,这只有在始终至少有一个订阅者订阅源的情况下才能正常工作(处理所有其他订阅者后的第一个订阅者将再次 运行 承诺,并将收到之前的两个 -缓存值及其对 运行).
的承诺结果这里有一个答案,它不需要使用简单的帮助程序始终在源头至少有一个订阅者:
var _p = null;
var once = function() { return _p || (_p = _this.getMyPromise());
var source = Rx.Observable.defer(once);
或者,如果您使用的是 lodash,您可以 _.memoize
您的 getMyPromise
并自动获取它。