javascript - 如何使用 Rxjs switchMap 抛出错误

标签 javascript browser rxjs rxjs6

我已经为 fetch 函数创建了一个包装器。根据下面的代码,test_3 通过了,但是 test_1 和 test_2 怎么会命中成功回调而不是错误回调呢?我怀疑我使用 throwError 的方式有问题。

import { from, throwError } from 'rxjs'; // version 6.5.2
import { retry, catchError, switchMap } from 'rxjs/operators';

function getBody(response: Response): Promise<any> {
  const headers = response.headers;

  if (headers.has('content-type')) {
    const contentType: string = headers.get('content-type');
    if (contentType.includes('json')) return response.json();
  }
  return response.text();
}

const http = (url) => 
  from(fetch(new Request(url))
    .pipe(
      retry(3),
      catchError(error => { // fetch will throw error if page not found.
        console.log('hit catchError')
        return of(new Response(null, { status: 404, statusText: 'Page not found' }));
      }),
      switchMap(async (response: Response) => {
        console.log('response.ok = ', response.ok);
        return response.ok
          ? getBody(response) // all status >= 200 and < 400 
          : throwError({ 
              status: response.status, 
              statusText: response.statusText, 
              body: await getBody(response) 
            });
      }),
    );

// test_1
http('http://this_url_not_exists.com').subscribe(
  response => console.log('should not hit this'),
  errorResponse => console.log('should errorResponse.status = 404'),
);
// test_1 console result:
// hit catchError
// response.ok = false
// should not hit this

// test_2
http('http://this_url_require_authentication.com').subscribe(
  response => console.log('should not hit this'),
  errorResponse => console.log('should errorResponse.status = 401'),
);
// test_2 console result:
// response.ok = false
// should not hit this

// test_3
http('http://myurl.com').subscribe(
  response => console.log('should hit this'),
  errorResponse => console.log('should not hit this'),
);
// test_3 console result:
// response.ok = true
// should hit this

请不要建议我使用rxjs的ajax。

最佳答案

fetch 不会为你抛出错误

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

The Promise returned from fetch() won’t reject on HTTP error status even if the response is an HTTP 404 or 500. Instead, it will resolve normally (with ok status set to false), and it will only reject on network failure or if anything prevented the request from completing.

更新: 看起来您的 api 调用正在返回 401 并且将在 fetch promise 中被拒绝,但您仍然不能依赖 fetch 来正确拒绝。请看下面的主题

https://github.com/github/fetch/issues/201

关于你的代码,它不被 switchMap 处理的原因是你返回 throwError 这不是一个 promise (你用异步标记函数)

throwError(...) 更改为 throwError().toPromise() 将正常工作。但同样不要依赖 fetch 来正确拒绝

关于javascript - 如何使用 Rxjs switchMap 抛出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56140700/

相关文章:

javascript - 禁用不被视为 HTML 属性

javascript - 我很好奇python是如何连接到网站的

css - 无论浏览器尺寸如何,固定 div

javascript - 合并连续的观测值

javascript - RxJS 根据发出的值重复

javascript - 为什么 .add() 不在列中插入值?

javascript - 标题中的 jQuery 移动可折叠按钮,停止折叠/展开

html - 在触摸设备上的浏览器中禁用双击 "zoom"选项

html - 如何设置默认浏览器窗口坐标 View ?

angular - 如何在 RxJS 5.5 中捕获错误