Javascript 如果完成,则RxJs取最后一个,否则在值之间插入延迟
我会给出完整的解释,但基本上我需要确保Javascript 如果完成,则RxJs取最后一个,否则在值之间插入延迟,javascript,rxjs,Javascript,Rxjs,我会给出完整的解释,但基本上我需要确保 发出的值之间有一些延迟 如果观测值已完成,只需返回最新值 比 我有两个观测值,每个都发出0或1个值,然后完成: //1. lazy observable that emit 0 or two value created at time of subscription and then completes const cache$ = this.getFromCacheLazy(); //2. ReplaySubject, that emits v
//1. lazy observable that emit 0 or two value created at time of subscription and then completes
const cache$ = this.getFromCacheLazy();
//2. ReplaySubject, that emits value in 1-1500ms and completes
const request$ = this.executeRequest();
我将其组合为observable,即首先发出缓存值(如果有),然后请求值:
const cacheAndRequest$ = concat(cache$, request$);
一段时间后我订阅了它:
setTimeout(() => {
cacheAndRequest$.Subscribe(console.log);
}, someDelay)
我该怎么办
修改或管道缓存和请求$
,以便:
$request
已完成,
必须忽略缓存$值
- 提示:如果$request已完成,则cacheAndRequest$也将在订阅时完成
$request
未完成,请立即从$cache发出值,并在500毫秒后从$request发出值。换句话说,这两个值之间必须存在延迟复制代码为了实现这一点,我对您的
缓存$
和请求$
进行了一些修改,以识别可观察到的:
const cache$ = getFromCacheLazy().pipe(
map(cache => {
return {source: 'cache', value: cache};
})
);
const request$ = executeRequest().pipe(
map(request => {
return {source: 'request', value: request};
})
);
我把concat
留给你了
然后我应用了withLatestFrom
函数来获取最新的发射值。如果最新发出的值来自请求$
我将返回它,否则我将连接可观测值以返回缓存$
值,并至少等待500毫秒发出请求$
:
const $subscribeDelayed = timer(subscriptionDelay)
.pipe(
withLatestFrom(cacheAndRequest$), // Provide the latest value from cacheAndRequest$
switchMap(res => {
// if request$ is already completed at the time of subscription, cache$ value is ignored
// else cache$ is emitted and request$ is emitted after at least 500ms
return res[1].source === 'request'
? of(res[1].value)
: concat(
of(res[1].value),
request$.pipe(
delay(500),
map(res => res.value)
)
);
}),
tap(res => console.log(res)),
);
看。这是一个有趣的问题。我得考虑一下。我认为主要问题是,
concat()
无法帮助您完成请求$
。您需要forkJoin()
或combinelatetest()
,尽管最后一个创建操作符将阻止任何发出的值,直到请求$
给您一些信息。我想说,您需要merge()
并为两个流提供一个startWith()
,这样就有了一个基本值。我不确定是否有RxJS有效的方法来检查其中一个流是否已经完成。CombineTest
其中流有一个startWith()
将允许您确定某种状态。它会给你像[value,0]
之类的东西;当你要complete()
流时,你发送另一个值,比如1
,你会得到[value,1]
,并且能够确定逻辑上的差异。关于延迟的另一个想法取决于你的可观察对象的内部状态。您可以在之后switchMap()
,并在其中创建一个一次性可观察对象。根据确定的状态,您可以返回(值)的或(值)的管道(延迟(500))
等等。解释起来有点复杂,但它会产生一个可读性很好的流。如果你更新了问题,请给我一个ping(在这里或在Twitter上)。我想这是一个有趣的问题,我很乐意去看看你们的操场。我已经更新了,见最后一行。之后,让我们删除评论。提示:我认为需求#1可以通过debounceTime(0)来解决,因为如果响应一点也不差,那么会将2个值合并为1。其实很简单。然而,我能够用去BounceTime(0)
解决#2问题,这可以防止在订阅时完成可观察时同时执行缓存和响应。它可以工作,因为$cache总是在订阅时发出并完成