ajax.post
YES
pre
,等待1秒,发出post
我为最后一颗子弹而苦苦挣扎,这是我在操场上的代码-https://rxviz.com/v/WJxGMl4O
这是我的管道部分:
action$.pipe(
flatMap(action =>
defer(() => ajax.post('foo foo foo')).pipe(
tap(res => console.log('succeeded:', res)),
mapTo('YES'),
retryWhen(error$ =>
error$.pipe(
tap(error => console.log('got error:', error)),
merge(of('pre')), // this isnt emiting
delay(1000),
merge(of('post')) // this isnt emitting
)
)
)
)
)
答案 0 :(得分:2)
我认为您可以使用catchError
而不是retryWhen
来实现所需的目标,因为retryWhen
仅对next
通知做出反应,而不会进一步传播它们。使用catchError
,您还可以获得源Observable,可以将其返回并重新订阅。 concat
仅在前一个消息完成后才一个个地订阅所有源,因此它将先发送两条消息pre
和post
,然后重试。
action$.pipe(
filter(action => action === 'hi'),
mergeMap(action =>
defer(() => resolveAfter(3)).pipe(
tap(res => console.log('succeeded:', res)),
mapTo('YES'),
catchError((error, source$) => {
console.log('retrying, got error:', error);
return staticConcat(
of('pre'),
of('post').pipe(delay(1000)),
source$,
);
}),
)
),
//take(4)
)
您的更新演示:https://rxviz.com/v/A8D7BzyJ
答案 1 :(得分:1)
这是我的方法:
首先,我创建了2个自定义运算符,一个将处理'pre'和'post'(skipValidation
),另一个将处理逻辑(useValidation
)。
const skipValidation = src => of(src).pipe(
concatMap(
v => of('post').pipe(
startWith('pre'),
delay(1000),
),
),
);
下面的代码段中值得注意的是action$.next({ skip: true })
。这样,我们将发出将通过 iif运算符的新值,以便我们可以发出'pre'和'post';
const useValidation = src => of(src).pipe(
filter(action => action === 'hi'),
mergeMap(action =>
defer(() => resolveAfter(3)).pipe(
tap(res => console.log('succeeded:', res)),
mapTo('YES'),
delay(1000),
retryWhen(error$ =>
error$.pipe(
tap(error => { console.log('retrying, got error:', error); action$.next({ skip: true })}),
delay(1000),
)
)
)
)
);
action$.pipe(
tap(v => console.log('v', v)), // Every emitted value will go through the `iif ` operator
mergeMap(v => iif(() => typeof v === 'object' && v.skip, skipValidation(v), useValidation(v))),
)