订阅后如何对数据进行排序?附代码片段求助
解决异步订阅后的数据排序问题
首先得指出你当前代码里的一个关键问题:subscribe是异步操作,循环里的每个请求完成时间是不确定的,所以desordrePlage数组里的元素顺序很可能和你循环的i顺序不一致,直接在循环内push后排序的话,要么时机不对(还有请求没完成),要么最终数组顺序混乱。
最稳妥的方式是等所有异步请求都完成后,再统一构建数组并排序,这里可以用RxJS的forkJoin操作符来实现,它会等待所有传入的Observable都完成后,返回一个包含所有结果的数组。
修改后的代码示例
plageHoraire(): void { console.log("analyse plage horaire ....."); // 1. 先创建所有需要执行的Observable数组,同时保存对应的i值 const obsArray = []; for (let i = 0; i < this.plageJour; i++) { // 用pipe(map)把请求结果和对应的i关联起来 const obs = this.isPlageReserver(this.debJ0H['debJour0H'], i).pipe( map(data => ({ afficheH: this.trancheDeb + i, unavailable: data })) ); obsArray.push(obs); } // 2. 用forkJoin等待所有请求完成 forkJoin(obsArray).subscribe((desordrePlage) => { // 3. 对完整的数组进行排序,按afficheH升序排列 const sortedPlage = desordrePlage.sort((a, b) => a.afficheH - b.afficheH); // 这里可以使用排序后的数组做后续操作 console.log("排序后的时段数据:", sortedPlage); }); }
关键说明
forkJoin确保所有异步请求都完成后才会执行后续逻辑,避免了异步顺序导致的数组混乱sort方法里的回调函数(a, b) => a.afficheH - b.afficheH是按afficheH的数值升序排序,如果需要降序,改成b.afficheH - a.afficheH即可- 如果你的项目里还没引入
forkJoin和map,需要先导入:import { forkJoin } from 'rxjs'; import { map } from 'rxjs/operators';
备选方案(不推荐)
如果一定要在每个请求完成后就维护有序数组,可以在每次push后调用sort,但这种方式效率低,且可能因为异步顺序导致中间状态的数组多次排序,代码示例:
plageHoraire(): void { let desordrePlage = new Array(); console.log("analyse plage horaire ....."); for (let i = 0; i < this.plageJour; i++) { this.isPlageReserver(this.debJ0H['debJour0H'], i).subscribe(data => { desordrePlage.push( { "afficheH": this.trancheDeb + i, "unavailable": data } ); // 每次push后立即排序 desordrePlage.sort((a, b) => a.afficheH - b.afficheH); console.log("当前排序后的数组:", desordrePlage); }); } }
但还是更推荐第一种forkJoin的方式,逻辑更清晰,性能也更好。
内容的提问来源于stack exchange,提问作者geek pédagogique lcms
相关产品推荐
相关产品推荐

