英文:
Is it possible to write an rxjs operator that controls subscription to it's source?
问题
让我们假设我有一个名为 source
的可观察对象,它具有以下属性:
- 第一次订阅时,它会发出网络请求
- 它是幂等的,因此在第一次订阅后,它总是发出相同的值
- 它的优先级较低,因此我们不希望过于急切地订阅它
理想情况下,如果有一种名为 delaySubscriptionUntil
的操作符,它可以延迟订阅,直到另一个可观察对象 s
发出一个值。
例如:
const s = new Subject<void>();
const l = source
.pipe(
delaySubscriptionUntil(s));
l.subscribe(console.log);
// 上面的代码不会输出任何内容,直到执行下面这行代码
s.next();
我查看了文档以查找是否存在这样的现有操作符,但没有找到。
英文:
Let's say I have an observable source
that has the following properties:
-
It makes a network request the first time it's subscribed to
-
It's idempotent, so it will always emit the same value after it's first subscribed to
-
It's low priority, so we don6t6 want to be too eager in subscribing to it
What would be ideal is if there were some sort of operator delaySubscriptionUntil
that would delay subscription until some other observable s
emits a value.
So for example:
const s = new Subject<void>();
const l = source
.pipe(
delaySubscriptionUntil(s));
l.subscribe(console.log);
// The above won't print anything until this line executes
s.next();
I looked through the documentation to see if there's an existing operator like this, but haven't found one.
答案1
得分: 1
以下是您要翻译的内容:
You just put the subject first and switchMap
只需将主题放在前面并使用 switchMap
const l = s.pipe(
switchMap(() => source)
);
一旦主题发出,源将被订阅。
一旦主题发出,源将被订阅。
Any thing that is after wont work as it relies on the previous observable emitting a value. You can have a filter in the chain that stops the previous observable's emission being emitted but there is nothing you can pass back up the chain to control outer subscriptions.
任何在之后的部分都不会起作用,因为它依赖于前一个可观察对象发出一个值。您可以在链中添加一个过滤器,以阻止前一个可观察对象的发射,但没有办法将控制外部订阅的信息传递回链中。
You could use a takeWhile
您可以使用 takeWhile
let allow = false;
const l = source.pipe(
takeWhile(allow)
);
但在这里,对源的订阅仍然处于活动状态,它正在发出值,只是被阻止传递。
So you could make a similar operator that keeps an internal flag and is flipped by a subject but source is still going to be emitting, you are just filtering values. You could buffer up the values if you don't want to lose them.
因此,您可以创建一个类似的操作符,它保留内部标志,并由主题翻转,但源仍然会发出值,您只是在筛选值。如果您不想丢失这些值,您可以将它们缓冲起来。
英文:
You just put the subject first and switchMap
const l = s.pipe(
switchMap(() => source)
);
Once the subject emits then the source will be subscribed to.
Any thing that is after wont work as it relies on the previous observable emitting a value. You can have a filter in the chain that stops the previous observable's emission being emitted but there is nothing you can pass back up the chain to control outer subscriptions.
You could use a takeWhile
let allow = false;
const l = source.pipe(
takeWhile(allow)
);
but here the subscription to source is active, it is emitting values, they are just stopped from being passed through.
So you could make a similar operator that keeps an internal flag and is flipped by a subject but source is still going to be emitting, you are just filtering values. You could buffer up the values if you don't want to lose them.
答案2
得分: 0
你可以使用 share()
,它将共享它之前发生的任何结果,直到你使用新的 URL 调用 sub.next()
,然后请求将再次发生。
const sub = new BehaviorSubject<string>('http://example.com/api');
const result$ = sub.pipe(
exhaustMap(url => this.http.get(url)),
share()
)
// 这些订阅中的每一个都会共享结果。
// HTTP 请求将仅调用一次,
// 直到你向 BehaviorSubject 发送新的 URL。
result$.subscribe(val => console.log(val));
result$.subscribe(val => console.log(val));
result$.subscribe(val => console.log(val));
result$.subscribe(val => console.log(val));
英文:
You could use share()
which will share the result of anything that happened before it until you call sub.next()
with a new url then the request will happen again.
const sub = new BehaviorSubject<string>('http://example.com/api');
const result$ = sub.pipe(
exhaustMap(url => this.http.get(url)),
share()
)
// Each one of these subscriptions will share the result.
// The http request will be called only once
// until you send a new url to the BehaviorSubject.
result$.subscribe(val => console.log(val));
result$.subscribe(val => console.log(val));
result$.subscribe(val => console.log(val));
result$.subscribe(val => console.log(val));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论