2

我正在压缩三个 observable,三个 observable 中的每一个都有自己的“成功”回调,使用.pipe(tap() => {...});. 当所有三个 observables 都没有错误地执行时,这可以正常工作,但是如果 observables 之一出错,那么所有的 tap 方法都不会执行。如果该 observable 成功运行,我怎样才能让 tap 方法始终执行?

var request1 = Observable.create(...);  //Pretend this one will fail (though request2 or request3 could also fail)
var request2 = Observable.create(...);
var request3 = Observable.create(...);

request1.pipe(tap(() => {
    //Unique success callback should always run if request1 succeeds, even if request2 or request 3 fails.
}));

request2.pipe(tap(() => {
    //Unique success callback should always run if request2 succeeds, even if request1 or request 3 fails.
}));

request3.pipe(tap(() => {
    //Unique success callback should always run if request3 succeeds, even if request1 or request 2 fails.
}));

var observable = zip(request1, request2, request3);
observable.subscribe(() => {
    //Do something when all three execute successfully
});
4

3 回答 3

2

我相信这是预期的,并且是您正在处理的适当行为。您可能希望查看使用管道将catchErrorlettable 传递到您的每个请求并返回一个空的 observable。

request1.pipe(tap(() => {
    //Unique success callback
}), catchError((err) => {
    return empty();
}));

这样你就可以处理那个 observable 的错误而不破坏新的zip.

于 2018-06-01T17:45:21.553 回答
1

@MichaelSolati 几乎是正确的,除了

  • 您应该捕获并返回一个值,例如,null如果您希望看到输出subscribe()- 因为 zip 不会触发empty()
  • 您的tap()回调不在zip()管道中,它们是未订阅的单独分支,因此永远不会激活。

请注意,随着 rxjs 版本的更改,导入可能会变得有些棘手,例如zip可用作函数和运算符。
使用下面片段中使用的rxjs.umd.jscdn,我最初错误地使用了运算符,它不会抛出错误(但不起作用)。

我从上面的评论中注意到您是在Angular上下文中执行此操作的。如果您仍然有问题,请发布带有导入的完整 Angular 模块,我们可以解决问题。

console.clear()
//console.log(rxjs)

// Get the operators and creators
const tap = rxjs.operators.tap
const empty = rxjs.empty
const zip = rxjs.zip
const catchError = rxjs.operators.catchError
const of = rxjs.of
const throwError = rxjs.throwError


//var request1 = of(1)
var request1 = throwError('error') 
var request2 = of(2)
var request3 = of(3)

var req1 = request1.pipe(
  tap(() => console.log('request1')),
  catchError((err) => { 
    console.log('request1 has error')
    return of(null) 
  })
);

var req2 = request2.pipe(
  tap(() => { console.log('request2');})
);

var req3 = request3.pipe(
  tap(() => { console.log('request3');})
);

var myObservable = rxjs.zip(req1, req2, req3);
myObservable.subscribe(
  result => { console.log('result', result) }
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.2.0/rxjs.umd.js"></script>

于 2018-06-03T00:54:08.430 回答
0

在您的代码中添加catch块,您可以在其中跟踪错误。

request1.pipe(tap(() => {
    //Unique success callback I want to run if request2 succeeds.
    //It should still run if request1 fails
}),
    catchError(// Error occured)
);
于 2018-06-01T17:44:43.153 回答