rxjs 在订阅时只使用一次 promise [英] rxjs using promise only once on subscribe

查看:97
本文介绍了rxjs 在订阅时只使用一次 promise的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想第一次使用 rxjs 但有点卡住了,因为它的行为不像我想要的那样:在我的场景中,我想从承诺中创建一个可观察的.但我希望承诺只被调用一次(不是在每次订阅时),并且我希望它不在创建时被调用(将调用推迟到第一个订阅).

I wanted to use rxjs for the first time but am a bit stucked 'cause it doesn't behave exactly like I want it to: In my scenario I want to create an observable from a promise. But I want the promise only being called once (not on every subscription) and I want it not being called on creation time (defer the call to the first subscription).

首先我尝试了这个:

var source = Rx.Observable.fromPromise(_this.getMyPromise())

导致在创建时调用 getMyPromise 函数.这并不令人满意,因为当时我不知道是否真的会使用源.

which causes a call to the getMyPromise function right on creation time. This is not satisfying because at that time I don't know if the source really will be used.

然后我尝试了:

var source = Rx.Observable.defer(function() { return _this.getMyPromise() })

每次对源进行新订阅时都会调用 getMyPromise 函数.这会给 Web 服务器带来太多不必要的调用.Rx.Observable.create 函数似乎有同样的问题.

which causes a call to the getMyPromise function each time a new subscription is being made to source. This makes way too many unnecessary calls to the web server. The Rx.Observable.create function seems to have the same issue.

那么还剩下什么或者我错过了什么?

So what is left or what am I missing?

推荐答案

.shareReplay() 这样做,例如:

var source = Rx.Observable.defer(function() { return _this.getMyPromise() }).shareReplay();

如果您使用的是 rxjs5,您需要阅读:shareReplay 的模式(1) 在 RxJS5 中

If you're using rxjs5, you'll want to read: Pattern for shareReplay(1) in RxJS5

在回答您在下面的评论时,我可以想到对上述逻辑进行相当简单的扩展,可以满足您的要求,但有一个警告.假设您要用于触发刷新"的事件在流 s$ 中表示,那么您可以执行以下操作:

In answer to your comment below, I can think of a fairly straightforward extension to the above logic that will do what you want, but it has a caveat. Let's say the events you want to use to trigger a "refresh" are represented in a stream, s$, then you could do something like:

var source = Rx.Observable.of({}).concat(s$)
    .flatMapLatest(function() {
        return Rx.Observable.defer(function() {
            return _this.getMyPromise()
        })
    })
    .shareReplay(1)

我们这里有一个流,从一个虚拟对象开始,让事情滚动,然后是一个由刷新事件组成的流.每一个都被投射到一个新的 observable 中,这个新的 observable 通过对 getMyPromise 方法的新调用而创建,并且整个事情被扁平化成一个单一的流.最后,我们保留了 shareReplay 逻辑,所以我们只在需要的时候才真正调用.

What we have here is a stream starting with a dummy object to get things rolling, followed by a stream consisting of your refresh events. Each of these is projected into a new observable created from a fresh invocation of your getMyPromise method, and the whole thing is flattened into a single stream. Finally, we keep the shareReplay logic so we only actually make calls when we should.

需要注意的是,只有在源至少有一个订阅者的情况下,这才会正常工作(在所有其他订阅者都被释放后的第一个订阅将再次运行承诺,并且将同时收到先前缓存的值和结果它导致运行的承诺).

The caveat is that this will only work properly if there's always at least one subscriber to the source (the first subscription after all others are disposed will run the promise again, and will receive both the previously-cached value and the result of the promise it caused to run).

这篇关于rxjs 在订阅时只使用一次 promise的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆