【问题标题】:RxJS Pipe Not Called With zip未使用 zip 调用 RxJS 管道
【发布时间】:2018-06-01 17:33:40
【问题描述】:

我正在压缩三个 observable,三个 observable 中的每一个都有自己的“成功”回调,使用 .pipe(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
});

【问题讨论】:

  • 这和角度有什么关系?
  • @Jota.Toledo 您是否因为我在示例中使用Observable.create 而不是httpClient.post 而投了反对票?

标签: rxjs rxjs-pipeable-operators


【解决方案1】:

我相信这是意料之中的,也是您正在处理的事情的适当行为。您可能希望查看使用管道将 catchError lettable 传递到您的每个请求中并返回一个空的 observable。

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

这样您就可以在不破坏新的zip 的情况下处理该可观察对象的错误。

【讨论】:

  • 感谢您的反馈,但我认为这不是我想要的。我在上面更新了我的 cmets 以进行澄清。
【解决方案2】:

@MichaelSolati 几乎是正确的,除了

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

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

我从上面的 cmets 中注意到,您是在 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>

【讨论】:

    【解决方案3】:

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

    request1.pipe(tap(() => {
        //Unique success callback I want to run if request2 succeeds.
        //It should still run if request1 fails
    }),
        catchError(// Error occured)
    );
    

    【讨论】:

    • 感谢您的反馈,但我认为这不是我想要的。我在上面更新了我的 cmets 以进行澄清。
    猜你喜欢
    • 2020-03-24
    • 2021-07-09
    • 1970-01-01
    • 1970-01-01
    • 2019-02-10
    • 2019-02-10
    • 2020-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多