Angular 6/Rxjs - 基础知识:可观察到的成功,错误,最后

Sim*_*you 26 finally observable rxjs angular

我正在构建一个最新的Angular 6架构并且来自AngularJS,这是我无法平衡的事情:HTTP请求的基本处理.

所以,为了这个问题,让我们说我想要一个可观察的.因为它似乎是Angular的未来.

在AngularJS中,我从非常优雅的东西出发:

   service.getAll()
    .then(onSuccess) // I process the data
    .catch(onError) // I do whatever needed to notify anyone about the issue
    .finally(onFinally); // I stop the loading spinner and other stuff
Run Code Online (Sandbox Code Playgroud)

现在在Angular 6/RxJS 6中,我不明白为什么一切都那么复杂,看起来不对.

我可以找到两种方法来做同上面的事情:

  1. 满管

    this.service.getAll()
        .pipe(
            map((data) => this.onSuccess(data)),
            catchError(error => of(this.handleError(error))),
            finalize(() => this.stopLoading())
        )
        .subscribe();
    
    Run Code Online (Sandbox Code Playgroud)

由于我们必须使用管道进行最终化,我不妨使用管道来处理所有事情,我认为最好的做法是让一切都按照相同的顺序排列.但现在我们不得不抛出一些东西,称之为"不太容易理解",我不喜欢这样.

  1. 半管所以我尝试了另一个想法,只有我需要的管道(敲定),我保留订阅回调.

    this.service.getAll()
    .pipe(
        finalize(() => this.stopLoading())
    )
    .subscribe(
        (data) => this.onSuccess(data),
        (error) => this.handleError(error)
    );
    
    Run Code Online (Sandbox Code Playgroud)

但是,好吧.是不是有点落后?我们仍然没有实际名称的回调,我们在阅读处理和错误之前完成.奇怪的.

所以我肯定不明白.我在网上找不到任何与此基本问题相关的内容.你要么有人想要"成功又最后",或者"成功和错误",但没有人想要其中的3个.也许我太老了,我不明白最新的最佳实践(如果是这样,请教育我!).

我的需求很简单:
1.我想处理从服务中获取的数据
2.我想得到错误以便显示给用户
3.我想停止在调用之前刚启动的加载微调器,或者一旦第一个完成成功或错误(我真的想要最终),再打一次电话

如何使用observable处理基本的HTTP调用?

(我不想要任何.toPromise,请,我想了解如何处理新的东西)

mar*_*tin 29

我认为有一个关键的误解:

你要么有人想要"成功又最后",或者"成功与错误",但没有人想要其中的3个.

这不完全正确.每个Observable都可以发送零个或多个next通知和一个errorcomplete通知,但不能同时发送.例如,当成功进行HTTP调用时,您将获得一个next和一个complete通知.在错误的HTTP请求中,您只有一个error通知,而这就是全部.请参见http://reactivex.io/documentation/contract.html

这意味着你永远不会有一个Observable发射errorcomplete.

然后是finalize运营商.处理链时调用此运算符(包括普通取消订阅).换句话说,它两者errorcomplete通知之后被调用.

所以你的第二个例子是正确的.我知道你finalize在订阅之前包含的内容看起来很奇怪,但实际上来自Observable的每个排放首先从顶部到底部到达订阅者,如果它errorcomplete通知它触发处理器处理器自下而上(以相反的顺序)并且此时finalize叫做.请参阅https://github.com/ReactiveX/rxjs/blob/master/src/internal/Subscriber.ts#L150-L152

在您的示例中,使用finalize与将dispose处理程序自己添加到Subscription对象中相同.

const subscription = this.service.getAll()
  .subscribe(
    (data) => this.onSuccess(data),
    (error) => this.handleError(error)
  );

subscription.add(() => this.stopLoading());
Run Code Online (Sandbox Code Playgroud)

  • 这与我的想法非常接近。谢谢你的解释。我只使用“添加”一词,而不是“最后”一词,但是由于它的阅读顺序正确,我认为这是可以的。`this.service.getAll()。subscribe(成功,错误).add(最终);` (3认同)

Pic*_*cci 5

所述subscribe可观测的方法接受3个可选功能作为参数

  • 第一个处理与Observable引发的事件一起提供的数据的数据
  • 第二个错误发生时处理任何错误
  • 第三个人在可观察对象完成时做点什么

因此,如果我理解正确,则可以使用如下所示的代码实现所需的功能

this.service.getAll()
.subscribe(
    data => this.onSuccess(data),
    error => this.handleError(error),
    () => this.onComplete()
);
Run Code Online (Sandbox Code Playgroud)

考虑到如果要retry在竞争条件下(通过使用switchMap运算符)重试(请参阅运算符),对HTTP调用使用Observables可以带来好处。我认为这些是Angular团队为http客户端选择这种方法的主要原因。

一般而言,我认为这是值得入手知道如何观测量工作和一些最重要的运营商(除上面,我首先想到的那些mergeMapfilterreduce-但是也有许多人),因为它们可以显著简化许多重要异步非阻塞环境中的任务,例如浏览器(或节点)。

  • 可悲的是,如果我错了,请纠正我,当一切顺利时,会激发`.subscribe`签名中的“ complete”参数。发生错误时不会触发。我了解Observable的好处,但我并不反对它们。我只想确定如何执行此基本操作(也许是为什么它不再是基本的良好实践)。 (3认同)