问题背景
客服反馈后端上送的原始数据与报表展示的数据顺序不一致,例如:
原始数据
日期 | 数据 |
---|---|
20211123 | xxxx |
20211120 | xxxx |
20211128 | xxxx |
20211130 | xxxx |
20211210 | xxxx |
20211203 | xxxx |
实际表格展示
日期 | 数据 |
---|---|
20211120 | xxxx |
20211123 | xxxx |
20211128 | xxxx |
20211130 | xxxx |
20211203 | xxxx |
20211210 | xxxx |
这是表格成精了?会自动排序了?于是,我又看了下其他的表格
原始数据
类型 | 数据 |
---|---|
老师 | 最美 |
医生 | 最美 |
程序员 | 最美 |
真实数据
类型 | 数据 |
---|---|
老师 | 最美 |
医生 | 最美 |
程序员 | 最美 |
这不一样?这表格还看数下饭?诶,好像只有key是数字的时候会出现自动排序的行为,几经验证,确实如此!
问题排查
出了线上Bug还能咋办,当然是翻代码,查commit-log,突然发现在经过一次数据处理的时候,数组顺序变了!
问题定位
const column0Array = Object.keys(column0Map).map((val) => {
// 处理逻辑
{
...
}
arr.push(column0Map[val]);
});
这里column0Map存储的是“每个日期下的信息”,like:
{
20211203:{...},
20211130:{...},
20211128:{...},
20211210:{...},
...
}
大概做的事情是,需要根据column的key按照顺序存到一个数组,但是!问题来了,这里的Object.keys()竟然偷偷地进行排序了!离谱?
验证猜想
问题原因
integer properties are sorted, others appear in creation order. —— 《现代 JavaScript 教程》
解释:在key为Number时,会被排序先,其他情况按照原始顺序
解决方案
1.维护一个原有key的arr,保证顺序,like:
const keysArr = [20211203,20211130,20211128,20211210];
keysArr.forEach(()=>{...})
2.改变数据结构为数组,like:
const keysArr = [{key:20211203,value:{...}},...];
keysArr.forEach(()=>{...})
总结
对象的遍历是不保证顺序的,对于需要保证顺序的数据,可以转化为数组先,就是多一个key的事~