RXJS只有在以前的值不是很好的情况下才订阅,我真的需要一个更好的
我有一个代价高昂的服务器ajax请求,它只有一个输入(RXJS只有在以前的值不是很好的情况下才订阅,我真的需要一个更好的,rxjs,rxjs6,Rxjs,Rxjs6,我有一个代价高昂的服务器ajax请求,它只有一个输入(full:boolean)。如果full为false,服务器可以返回部分或全部响应(response.isFull==true);但是如果full为true,服务器将返回完整响应。通常情况下,部分响应足够好,但在某些情况下需要完全响应。我需要尽可能避免明确地请求完整的响应,因此我想我应该从一个行为主题开始,如果我需要得到完整的响应,我最终可以使用true,并将其与distinctUntilChanged结合起来。这将给我一个初始值为false
full:boolean
)。如果full
为false
,服务器可以返回部分或全部响应(response.isFull==true
);但是如果full
为true
,服务器将返回完整响应。通常情况下,部分响应足够好,但在某些情况下需要完全响应。我需要尽可能避免明确地请求完整的响应,因此我想我应该从一个行为主题
开始,如果我需要得到完整的响应,我最终可以使用true
,并将其与distinctUntilChanged
结合起来。这将给我一个初始值为false
的可观察值,如果我将其输入到该值中,则可以给我true
:
const fullSubject = new BehaviorSubject<boolean>(false);
const fullSubject=新行为主体(false);
然后我得到了一个函数,它接受一个布尔参数,并返回一个可观察的服务器请求(重试、转换等)。如上所述,答案可以是部分的,也可以是完整的,但即使服务器自行判断输入参数为false,答案也可以是完整的。例如:
interface IdentityData {
...
isFull: boolean;
}
private getSimpleIdentity(full: boolean): Observable<IdentityData> {
return Axios.get(`/api/identity${full?"?full=true":""}`)
.pipe( ... retry logic ...,
... transformation logic ...,
shareReplay(1) );
}
接口标识数据{
...
isFull:布尔值;
}
私有getSimpleIdentity(完整:布尔):可观察{
返回Axios.get(`/api/identity${full?”?full=true):“}`)
.pipe(…重试逻辑。。。,
…转换逻辑。。。,
共享重播(1));
}
我需要知道如何将这些结合起来,以确保以下内容是正确的:
- 服务器最多需要查询两次
- 如果第一个答案是完整答案,则不必对服务器执行进一步的查询
- 如果第一个答案是部分答案,并且将
输入true
,则必须请求完整答案fullSubject
如果我没有弄错的话,请提前谢谢
private getSimpleIdentity(): Observable<IdentityData> {
return fullSubject.pipe(
switchMap(full => Axios.get(`/api/identity${full ? "?full=true" : ""}`)),
shareReplay(1),
);
}
我的做法如下:
const fullSubject=新行为主体(false);
const src$=fullSubject.pipe(
switchMap(isFull=>Axios.get(“…”),
取(2),//最多需要两次服务器
takeWhile(response=>!response.isFull,true),//当'isFull'时,它将完成并取消订阅->不再向服务器请求
共享重播(1),
);
src$.subscribe(()=>{/*…*/});
函数getFullAnswer(){
fullSubject.next(true);
}
takeWhile
接受一个,包含在内的
。当设置为true时,当谓词函数的计算结果为false(例如isFull为true)时,它也将发送该值 我不明白。我怎样才能将BehaviorSubject注入retryWhen?给我一个你想做的输入和输出我不知道如何比我解释得更好。我正在考虑制作一个图表,但我不确定它是如何工作的。这些要求对我来说没有多大意义。如果您需要完整的响应,为什么要先进行不确定的查询来浪费资源?为什么不直接请求你需要的资源呢?如果您已经知道所需资源的类型,为什么还要处理多个请求呢?听起来不错,我会立即检查。这对我帮助很大。只剩下一件事:在不创建新请求的情况下,如何在多个订阅者之间共享这些答案shareReplay(1)
最后可能会破坏逻辑,我想。如果你想在多个地方订阅“src$”而不触发多个请求,我想你可以在“takeWhile”之后添加shareReplay,而没有任何问题。所以,shareReplay
工作得很好,但是,takeWhile
将忽略带有response.isFull的答案。我在管道外部设置了一个变量,并使用prev=savedFull;savedFull=newFull;在takeWhile
条件内返回prev
。我不知道是否有更好的方法?哦,getPartialAnswer()
不是必需的,因为BehaviorSubject
已经以false开头了。很高兴你这么问takeWhile
接受一个,包括在内
。当设置为true
时,当谓词函数的计算结果为false(例如isFull
为true
)时,它也将发送该值。
const source = of("").pipe(map(() => Math.floor(Math.random() * 10 + 1)));
const example = source
.pipe(
tap((val) => console.log("tap", val)),
map((val) => {
//error will be picked up by retryWhen
if (val !== 5) throw val;
return val;
}),
retryWhen((errors) =>
errors.pipe(
tap(() => console.log("--Wait 1 seconds then repeat")),
delay(1000)
)
)
)
.subscribe((val) => console.log("subscription", val));
/*
output:
tap 3
--Wait 1 seconds then repeat
tap 8
--Wait 1 seconds then repeat
tap 1
--Wait 1 seconds then repeat
tap 4
--Wait 1 seconds then repeat
tap 7
--Wait 1 seconds then repeat
tap 5
subscription 5
*/