如何比较两个冷的 Observables 源(不是它们发出的潜在流)
How to compare two cold Observable's sources (not the potential streams they emit)
场景: 我正在使用 publishReplay 在 Angular 应用程序中缓存和重播某些 Http 请求(由于一些已修复的错误,使用 publishReplay 而不是 shareReplay在 rxjs 中)。
我的问题是,如果我检测到 URL 参数更改,我想强制缓存的可观察源更新自身并使用 publishReplay 创建一个新的缓存可观察的。我认为也许这可以通过 interrogating/comparing 新提议的可观察对象与现有缓存可观察对象的源代码来实现,但我未能成功实现这一目标。
我在寻找什么: 一种询问可观察对象来源的方法,以便我可以将其与另一个可观察对象的来源进行比较,看看它们是否相同(url 在这种情况下),或其他一些检测随 publishReplay 更改的 Http Observable 上的 url 的方法。此外,我试图将此逻辑抽象到缓存机制中,这样我就不必在整个应用程序中散布代码来检测参数是否发生变化。
这是一个我想做的事情的一个非常天真的例子,但它不起作用,输入源参数是新的 Observable,它包含一个 http 请求的句柄,而 origSource 是以前的 observable,它包含相同的内容(尽管可能带有 publishReplay 似乎不承认的不同 url 参数)。
// determine if key exists and source is un-modified (i.e params did not change)
protected isEntreeValid<T>(key: ICacheKeyConstantsModel, source: Observable<T>): boolean {
if (!this.has(key)) { return false; }
if (this.has(key)) {
let origSource = this.cache.registry.get(key).source; // observable previously cached used to resubscribe to later and returned cached publishReplay response, or can be tickled to make the original http request again effectively busting the cache.
console.log('source: ', source);
console.log('are they equal', source.source === origSource.source); //always returns false but assume need to check some inner value of observable anyways and do a fuzzy comparison.
if (source.source !== origSource.source) { return false; }
}
return true;
}
上面的方法:上面方法中的输入'source'参数只是一个指向http.get方法的指针,存储在[=70中的一个Map中=] 对时尚:
即地图
这样我们就可以更轻松地以集中的方式编组它们的缓存状态和其他属性。基本上就是在这里,如果 'key' 已经存在,我想评估 'source' 以查看 URL 上的参数是否已更改,如果有,我们可以破坏缓存,或者如果它们难道我们只是 return publishReplay 结果。
注意:在这种情况下我不会intend/want连接到 Observable,我只对比较这些 Observable 的来源感兴趣,而不是潜在的流他们会发射。
更新: 找到了我要找的东西,但不确定为什么它在下面是 WAAAY。有没有一种巧妙的方法可以迭代到这个,在结构上似乎与 Observables 一致,而不是我在创建这些 Observables 时所做的一些奇怪的事情。看起来很奇怪,这个非常基本的信息会在那里这么远(注意 url 已经被混淆并且这个例子没有参数):
属性 位置是: Observable.value.source.source.source.source.source
此位置的对象结构是:
{
value: HttpRequest
body: null
headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, headers: Map(0)}
method: "GET"
params: HttpParams {updates: null, cloneFrom: null, encoder: HttpUrlEncodingCodec, map: Map(0)}
reportProgress: false
responseType: "json"
url: "https://my-dev-server.com/primary/HealthCareApp/Patients"
urlWithParams: "https://my-dev-server.com/primary/HealthCareApp/Patients"
}
问题:有什么clean/reliably方法可以在不订阅的情况下展平或深入到最内层的 Observable?
更新二:
现在我正在使用类似下面的方法来提取 innerObservable,可能有更好的方法,但这是我们目前正在摇摆的方法:
// retrieve inner meta-data from cold observable for interrogation without subscribing
private extractInnerObservable<T>(source: Observable<T>): Observable<T> {
let target = observableOf(source)['value'];
while (target['source']) {
target = target['source'];
}
return target;
}
结果方法:
结论:仍然可以肯定地探索其他选项,但我已经多次更新这个问题以分享我现在所处的位置,至少现在处于解决原始问题的状态(虽然肯定不是以最优雅的方式)。然而,如果其他人正在为类似的想法而苦苦挣扎,那么分享这种疯狂的结果是有价值的。
我想在这里颠倒你的逻辑。如果有一些参数要更改缓存的请求,请使用运算符来完成...
private paramSource = new Subject<string>(); // whatever type is appropriate
cached$ = this.paramSource.pipe(
distinctUntilChanged(), // could add some custom compare function in here
switchMap(param => this.makeRequest(param)),
shareReplay(1) // whatever you wana do for caching
);
// call this whenever you might've wanted to run the observable inspection
updateParam(param: string) {
this.paramSource.next(param);
}
如果这直接实现了您的目标,则不是积极的,因为我不太清楚您的目标,但希望这很接近。
场景: 我正在使用 publishReplay 在 Angular 应用程序中缓存和重播某些 Http 请求(由于一些已修复的错误,使用 publishReplay 而不是 shareReplay在 rxjs 中)。
我的问题是,如果我检测到 URL 参数更改,我想强制缓存的可观察源更新自身并使用 publishReplay 创建一个新的缓存可观察的。我认为也许这可以通过 interrogating/comparing 新提议的可观察对象与现有缓存可观察对象的源代码来实现,但我未能成功实现这一目标。
我在寻找什么: 一种询问可观察对象来源的方法,以便我可以将其与另一个可观察对象的来源进行比较,看看它们是否相同(url 在这种情况下),或其他一些检测随 publishReplay 更改的 Http Observable 上的 url 的方法。此外,我试图将此逻辑抽象到缓存机制中,这样我就不必在整个应用程序中散布代码来检测参数是否发生变化。
这是一个我想做的事情的一个非常天真的例子,但它不起作用,输入源参数是新的 Observable,它包含一个 http 请求的句柄,而 origSource 是以前的 observable,它包含相同的内容(尽管可能带有 publishReplay 似乎不承认的不同 url 参数)。
// determine if key exists and source is un-modified (i.e params did not change)
protected isEntreeValid<T>(key: ICacheKeyConstantsModel, source: Observable<T>): boolean {
if (!this.has(key)) { return false; }
if (this.has(key)) {
let origSource = this.cache.registry.get(key).source; // observable previously cached used to resubscribe to later and returned cached publishReplay response, or can be tickled to make the original http request again effectively busting the cache.
console.log('source: ', source);
console.log('are they equal', source.source === origSource.source); //always returns false but assume need to check some inner value of observable anyways and do a fuzzy comparison.
if (source.source !== origSource.source) { return false; }
}
return true;
}
上面的方法:上面方法中的输入'source'参数只是一个指向http.get方法的指针,存储在[=70中的一个Map中=] 对时尚: 即地图 这样我们就可以更轻松地以集中的方式编组它们的缓存状态和其他属性。基本上就是在这里,如果 'key' 已经存在,我想评估 'source' 以查看 URL 上的参数是否已更改,如果有,我们可以破坏缓存,或者如果它们难道我们只是 return publishReplay 结果。
注意:在这种情况下我不会intend/want连接到 Observable,我只对比较这些 Observable 的来源感兴趣,而不是潜在的流他们会发射。
更新: 找到了我要找的东西,但不确定为什么它在下面是 WAAAY。有没有一种巧妙的方法可以迭代到这个,在结构上似乎与 Observables 一致,而不是我在创建这些 Observables 时所做的一些奇怪的事情。看起来很奇怪,这个非常基本的信息会在那里这么远(注意 url 已经被混淆并且这个例子没有参数):
属性 位置是: Observable.value.source.source.source.source.source
此位置的对象结构是:
{
value: HttpRequest
body: null
headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, headers: Map(0)}
method: "GET"
params: HttpParams {updates: null, cloneFrom: null, encoder: HttpUrlEncodingCodec, map: Map(0)}
reportProgress: false
responseType: "json"
url: "https://my-dev-server.com/primary/HealthCareApp/Patients"
urlWithParams: "https://my-dev-server.com/primary/HealthCareApp/Patients"
}
问题:有什么clean/reliably方法可以在不订阅的情况下展平或深入到最内层的 Observable?
更新二:
现在我正在使用类似下面的方法来提取 innerObservable,可能有更好的方法,但这是我们目前正在摇摆的方法:
// retrieve inner meta-data from cold observable for interrogation without subscribing
private extractInnerObservable<T>(source: Observable<T>): Observable<T> {
let target = observableOf(source)['value'];
while (target['source']) {
target = target['source'];
}
return target;
}
结果方法:
结论:仍然可以肯定地探索其他选项,但我已经多次更新这个问题以分享我现在所处的位置,至少现在处于解决原始问题的状态(虽然肯定不是以最优雅的方式)。然而,如果其他人正在为类似的想法而苦苦挣扎,那么分享这种疯狂的结果是有价值的。
我想在这里颠倒你的逻辑。如果有一些参数要更改缓存的请求,请使用运算符来完成...
private paramSource = new Subject<string>(); // whatever type is appropriate
cached$ = this.paramSource.pipe(
distinctUntilChanged(), // could add some custom compare function in here
switchMap(param => this.makeRequest(param)),
shareReplay(1) // whatever you wana do for caching
);
// call this whenever you might've wanted to run the observable inspection
updateParam(param: string) {
this.paramSource.next(param);
}
如果这直接实现了您的目标,则不是积极的,因为我不太清楚您的目标,但希望这很接近。