场景描述
最近在做一个 HRM 项目,测试提来一个 bug,在同一张 table 中,一会儿显示 13 条行,一会儿显式 18 条数据。
查找问题
只看复现结果,还以为是内存泄露造成,因为页面一卡一卡的。
看了代码才发现,原来另有乾坤。
async handleData (data) {
...
// 动态添加列
this.table.columns = this.table.columns.concat([
{
label: `${type.slice(-2)}前`,
prop: 'before',
render: (h, vm) => {
const { row, displayValue } = vm
return row.property === '附件' ? (
<i-upload value={row.before} readonly></i-upload>
) : displayValue
}
},
{
label: `${type.slice(-2)}后`,
prop: 'after',
render: (h, vm) => {
const { row, displayValue } = vm
return row.property === '附件' ? (
<i-upload value={row.after} readonly></i-upload>
) : displayValue
}
}
])
// 数据格式化
let list = displayList[this.baseForm.operateType]
list.forEach(async (k, i) => {
if (k in propertyMap) {
let formatter = propertyMap[k].formatter
let dateFormatter = propertyMap[k].dateFormatter
this.table.data[i] = {
property: propertyMap[k].label,
before: formatter
? await dictFormat(formatter, before[k])
: dateFormatter
? dateFormat(before[k])
: (before[k] || '-'),
after: formatter
? await dictFormat(formatter, after[k])
: dateFormatter
? dateFormat(after[k])
: (after[k] || '-')
}
}
})
}
出现问题的猜想
- 首先:table 的行和列是动态添加的。
- 其次:行的数据还是异步操作的结果。
- 最后:这些操作还直接绑定在 table 的数据上。
这样问题就出来了:
- 动态修改 table 绑定的行列数据,就会频繁修改页面,造成页面卡顿的问题。
- table 的列获得了一个有 Promise 对象的数组。Promise 对象的状态未知。
修改思路
- 不直接改 table 绑定的数据,新建一个临时变量,进行操作。
- 等待所有异步操作结束后,再进行赋值。
- 这里 forEach 改为 map,因为需要确认异步操作
async handleData (data) {
if (!data) return
...
// 动态添加列
this.tempTable.columns = this.tempTable.columns.concat([
{
label: `${type.slice(-2)}前`,
prop: 'before',
render: (h, vm) => {
const { row, displayValue } = vm
return row.property === '附件' ? (
<i-upload value={row.before} readonly></i-upload>
) : displayValue
}
},
{
label: `${type.slice(-2)}后`,
prop: 'after',
render: (h, vm) => {
const { row, displayValue } = vm
return row.property === '附件' ? (
<i-upload value={row.after} readonly></i-upload>
) : displayValue
}
}
])
// 数据格式化
let list = displayList[this.baseForm.operateType]
let temp = list.map(async (k, i) => {
if (k in propertyMap) {
let formatter = propertyMap[k].formatter
let dateFormatter = propertyMap[k].dateFormatter
return {
property: propertyMap[k].label,
before: (formatter
? await dictFormat(formatter, before[k])
: dateFormatter
? dateFormat(before[k])
: (before[k] || '-')),
after: formatter
? await dictFormat(formatter, after[k])
: dateFormatter
? dateFormat(after[k])
: (after[k] || '-')
}
}
})
this.tempTable.data = await Promise.all(temp)
this.table = this.tempTable
}
思考
- 查找问题时,在确定 Promise 都执行的情况下,为什么有时候显示 18 条,有时候显示 13 条呢?
相关文档