Angular升级Http至HttpClient后RxJS .first()操作符抛出类型错误
搞定HttpClient轮询204响应的类型错误问题
哈哈,这个坑我之前踩过!核心就是Angular的HttpClient和旧Http服务在处理204 No Content响应时的行为完全不一样,导致你的.first(data => data)触发了类型错误。
问题到底出在哪?
咱们先理清楚新旧服务的差异:
- 旧
Http服务:哪怕服务器返回204,它也会给你返回一个完整的Response对象(哪怕响应体是空的)。所以你之前的.first(data => data)里,data是一个实实在在的对象,真值判断永远为true,直到服务器返回有内容的响应。 HttpClient服务:它会自动解析响应体,而204响应本身就意味着「没有内容」,所以这时候它会直接返回null。这时候你的.first(data => data)相当于在判断null是否为真,TypeScript的类型检查会直接报错——因为HttpClient.get()默认的泛型是T,不是T|null,你用null做真值判断就违反了类型约定。
两种解决方案任你选
方案一:监听完整响应,过滤204状态
这种方式更灵活,能拿到完整的响应信息,适合需要判断状态码的场景:
return interval(this.pollInterval) .pipe( mergeMap(() => // 配置observe: 'response'来获取完整的响应对象 this.http.get<any>(`${this.apiUrl}/poll`, { observe: 'response' }) ), // 直接过滤掉204的响应 filter(response => response.status !== 204), // 提取出真正的响应体 map(response => response.body), // 现在data肯定是非空的,类型检查完全通过 first(data => !!data) );
方案二:直接处理null值,简化逻辑
如果不需要状态码这些额外信息,直接给get()指定泛型为T|null,然后过滤掉null即可:
return interval(this.pollInterval) .pipe( mergeMap(() => this.http.get<any | null>(`${this.apiUrl}/poll`)), // 只保留非null的有效数据 filter(data => data !== null), // 直接取第一个符合条件的结果,不用再写判断逻辑 first() );
小提示
以后用HttpClient的时候要注意:它会严格按照HTTP状态码来处理响应体,像204、205这类无内容的状态码,都会返回null,和旧Http的行为差异很大,升级的时候一定要留意这类边界场景哦!
内容的提问来源于stack exchange,提问作者Sawtan
相关产品推荐
相关产品推荐

