Announcement

👇Official Account👇

图片

Welcome to join the group & private message

Article first/tail QR code

Skip to content

HTTP 请求处理实战

RxJS 的 ajax 模块可以让你以 Observable 的方式处理 HTTP 请求。这使得处理复杂的请求场景(如取消请求、重试)变得非常简单。

基本用法

typescript
import { ajax } from 'rxjs/ajax';

const users$ = ajax.getJSON('https://api.github.com/users');

users$.subscribe(
  users => console.log(users),
  err => console.error(err)
);

高级错误处理:使用 retryWhen 实现指数退避

简单的 retry(3) 在很多场景下并不够用。如果一个服务暂时宕机,立即重试 3 次很可能会全部失败。更优雅的策略是"指数退避":每次重试前等待更长的时间,给服务器恢复的机会。

retryWhen 是一个强大的操作符,它让你能够根据错误流来决定是否以及何时进行重试。

示例:

typescript
import { ajax } from 'rxjs/ajax';
import { retryWhen, mergeMap, delay, tap } from 'rxjs/operators';
import { of, throwError, timer } from 'rxjs';

export const genericRetryStrategy = ({
  maxRetryAttempts = 3,
  scalingDuration = 1000,
  excludedStatusCodes = []
}: {
  maxRetryAttempts?: number,
  scalingDuration?: number,
  excludedStatusCodes?: number[]
} = {}) => (attempts: Observable<any>) => {
  return attempts.pipe(
    mergeMap((error, i) => {
      const retryAttempt = i + 1;
      if (
        retryAttempt > maxRetryAttempts ||
        excludedStatusCodes.find(e => e === error.status)
      ) {
        return throwError(error);
      }
      console.log(
        `Attempt ${retryAttempt}: retrying in ${retryAttempt * scalingDuration}ms`
      );
      return timer(retryAttempt * scalingDuration);
    }),
  );
};

// 使用
ajax.getJSON('/api/endpoint-that-fails').pipe(
  retryWhen(genericRetryStrategy({
    maxRetryAttempts: 4,
    scalingDuration: 2000,
    excludedStatusCodes: [400, 404]
  }))
).subscribe(
  result => console.log(result),
  error => console.error('Request ultimately failed:', error)
);

请求依赖

假设你需要先获取一个用户的 ID,然后再获取该用户的详细信息。

typescript
import { ajax } from 'rxjs/ajax';
import { switchMap } from 'rxjs/operators';

const user$ = ajax.getJSON('https://api.github.com/users/1').pipe(
  switchMap(user => ajax.getJSON(`https://api.github.com/users/${user.id}/repos`))
);

user$.subscribe(repos => console.log(repos));

上次更新于: