TypeScript Angular中playlist对象可见但访问tracks属性返回空数组问题
问题原因
- 代码中调用的
this.http.get是异步IO操作,订阅回调内的逻辑会在网络请求完成后才触发执行,而你写的console.log属于同步执行逻辑,执行时机在所有请求发起之后、请求返回之前,此时playlist.tracks还未被写入数据,因此直接打印会得到空数组。 - 浏览器控制台打印引用类型(普通对象、数组等)时,存储的是对象的内存引用而非打印时刻的快照。当你调用
console.log(this.playlist)时虽然tracks仍为空,但当你在控制台点击展开对象属性时,网络请求已经完成,tracks已经被填充,因此可以看到完整数据。 - 额外注意:你当前代码的分页参数
offset写法存在问题,offset代表跳过的条目数,正确计算方式应为(页码-1)*每页条目数,你直接写offset=${i}会导致获取到的曲目存在重复/遗漏。
解决方案
可以使用RxJS的forkJoin操作符批量处理所有分页请求,等待所有请求完成后再统一处理数据,此时就能正常访问完整的tracks数组:
// 生成所有分页请求的Observable数组 const trackRequests$ = Array.from({ length: iterationCount }, (_, index) => { // 纠正offset计算逻辑 const offset = index * PLAYLIST_ITEM_LIMIT; const endpointX = `${BASE_API_URL}playlists/${playlistId}/tracks?limit=${PLAYLIST_ITEM_LIMIT}&offset=${offset}&fields=${fieldString}`; return this.http.get<WritableTrackList>(endpointX); }); // 等待所有请求完成后统一处理数据 forkJoin(trackRequests$).subscribe(allResponse => { allResponse.forEach(data => { data.items.forEach(item => { const track: Track = this.helperService.trackApiObject2TrackObject(item.track); this.playlist.tracks.push(track); }); }); // 此处访问tracks即可拿到完整数据 console.log(this.playlist.tracks); });
如果需要逐批处理返回结果,可以在订阅回调中统计已完成的请求数量,和总请求数匹配时再执行后续逻辑。另外需要注意组件销毁时要取消所有订阅,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Hirusha Fernando
相关产品推荐
相关产品推荐

