rxjs处理异步请求

Abstract

Rxjs是Angular框架的官方推荐异步处理库,其内置丰富的operators,运算子,能够帮助我们解决大部分的业务难题。

学习前置条件

  • Observable 可观察的抽象接口,需要有next等方法,可以被订阅的。
  • Observer 观察者,可以不定时地发送新事件,有next, error, complete等方法。
  • Subscriber 订阅者,订阅了观察者,当观察者发出新事件时,订阅者的内容会自动触发执行。
  • Pipe 管道,事件流的载体。
  • Operator 运算子,有几种不同分类的,比如创建型,操控型,错误处理型。

Vs Promise

  • 状态改变区别 Promise的状态只能被改变一次,也就是then里面的方法只会执行第一次。而Observer.next()可以发送多次新值,其订阅的方法也会跟着执行多次,只有Observer.complete()后,这个观察者的状态才终止,next不会再触发新的事件。
  • 回调函数区别 一个变化多个响应时,promise需要.then进行添加多个处理,而Observer可以直接subscribe()多次,来实现多个回调方法。

演示

基础请求

新建request.ts:

import { Observable } from 'rxjs';

export function request(url: string) {
  return new Observable((observer) => {
    setTimeout(() => {
      observer.next(url + 'respone');
      observer.complete();
    }, 1000);
  });
}

export function badRequest(url: string) {
    return new Observable((observer) => {
        setTimeout(() => {
        observer.error(url + '500 Server');
        observer.complete();
        }, 1000);
    });
}

component.ts:

import { badRequest, request } from 'src/app/request';

  ngOnInit() {
    request('test.com').subscribe({
      next: (res) => console.log('成功: ', res),
      error: (err) => console.log('失败: ', err),
      complete: () => console.log('完成'),
    });

    badRequest('test2.com').subscribe({
      next: (res) => console.log('成功: ', res),
      error: (err) => console.log('失败: ', err),
      complete: () => console.log('完成'),
    });
  }

效果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

基础请求 + operator

import { catchError, of } from 'rxjs';

request('test.com')
      .pipe(
        catchError((err) => {
          console.log('接口错误');
          return of(err);
        })
      )
      .subscribe((res) => console.log(res));

badRequest('test2.com')
  .pipe(
    catchError((err) => {
      console.log('接口错误');
      return of(err);
    })
  )
  .subscribe((res) => console.log(res));

效果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

串行请求 + 高阶Observable

import { mergeMap } from 'rxjs';
import { request } from 'src/app/request';

request('foo')
  .pipe(
    mergeMap((res) => {
      console.log('res1: ', res);
      return request('bar');
    }),
    mergeMap((res) => {
      console.log('res2: ', res);
      return request('bazz');
    })
  )
  .subscribe((res) => console.log('res3: ', res));

效果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Tip: switchMap,concatMap,mergeMap都是用来处理返回Observable对象的Observer,这里当源observer只发送一个事件时,这些运算子的表现形式是一样的。

串行请求 + 高阶Observable + 捕获错误

import { catchError, mergeMap, throwError } from 'rxjs';
import { badRequest, request } from 'src/app/request';

const pipeErrorHandler = function (message: string) {
  return catchError((err) => {
    if (err && err.bad) {
      // 前面已有错误,且已被处理,直接return
      return throwError(() => err);
    }
    console.log(message);
    console.log('err: ', err);
    // 处理error
    // ...
    return throwError(() => ({ bad: true }));
  });
};

request('foo')
  .pipe(
    pipeErrorHandler('foo 请求失败'),
    mergeMap((res) => {
      console.log('res1: ', res);
      return request('bar');
    }),
    pipeErrorHandler('bar 请求失败'),
    mergeMap((res) => {
      console.log('res2: ', res);
      return badRequest('bazz');
    }),
    pipeErrorHandler('bazz 请求失败')
  )
  .subscribe({
    next: (res) => console.log('res3: ', res),
    error: (err) => {
      console.log('串行请求任务失败');
    },
  });

效果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

并行请求-forkJoin

import { forkJoin } from 'rxjs';

forkJoin({
  request1: request('foo'),
  request2: request('bar'),
  request3: request('bazz'),
}).subscribe({
  next: (value) => console.log(value),
  complete: () => console.log('complete'),
});

效果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

并行请求-forkJoin + 错误处理

forkJoin({
  request1: request('foo'),
  request2: request('bar'),
  request3: badRequest('bazz'),
}).subscribe({
  next: (value) => console.log(value),
  error: (err) => console.log('有错误:', err),
  complete: () => console.log('complete'),
});

效果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Tip: forkJoin的并发是全部成功才算成功,否则,抛出一个error。
想要源码的,欢迎来访问我的代码仓:
https://gitee.com/gao-hui007/my-blogs/blob/master/docs/angular/rxjs.md#
转载请说明

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值