一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情。
今天晚上改bug时碰见一个很奇怪的问题,也给大家分享一下。顺便总结一下我开发中常见的数组问题
map中嵌套异步操作
今天有一个小功能,是在三方接口里拉取一些数据,由于三方的图片设置了跨域,因此我通过原生的一个方法,把图片下载并转换为base64
伪代码基本如下,是一个vuex的actions:
async showPost({commit}){
const res = await getPost()
const list = res.map(e=>{
imageToBase64(e.url)
return {
url:e.url,
id:e.id,
highResolution:'',
lowResolution:require('../assets/images/default.png')
}
})
commit('savePost',list)
}
lowResolution就是数据还未返回时的默认图,imageToBase64会在成功的时候更新对应highResolution。vue组件则大概是这样
<template>
<div>
<img v-for="k in list" :key="k.id" :src="k.highResolution ?k.highResolution:k.lowResolution">
</div>
</template>
<script>
export default {
computed:{
list(){
return this.$store.state.postList
}
}
}
</script>
打眼一看,并没有是什么问题,但是真机上却出现随机显示lowResolution的情况,大部分状态都是lowResolution的情况,着实让我愣了一下。
最后经过n次debug,我才发现问题所在。imageToBase64本质上是一个异步的方法,而且当你嵌套进map时,有可能第一次的结果返回了,但是map还没有结束,返回的base64就无法更新到state。也有可能imageToBase64运行的很慢,可能你map都结束了,值才返回,这时候就是正确的。因此需要这样处理,把异步放到map之外
async showPost({commit}){
const res = await getPost()
const list = res.map(e=>({
url:e.url,
id:e.id,
highResolution:'',
lowResolution:require('../assets/images/default.png')
}))
commit('savePost',list)
state.postList.forEach(e=>{imageToBase64(e.url)})
}
确保值已经存入state后在去获取,这时候就不需要管imageToBase64什么时候返回了
循环中splice
这个应该属于一个思维误区,一般循环数组都是通过下表,如果此时你使用splice方法删除元素,数组的下标就会改变。
const arr = [1,2,3]
for(let i =0;i<arr.length;i++){
if(arr[i]===2){
arr.splice(i,1)
}
}
解决办法很简单:使用filter
const arr = [1,2,3].filter(e=>e!==2)
unshift 的返回值
在数组的操作中,concat会返回数组,但是push、unshift这些都是只返回数组的长度,这样就容易造成记忆混乱,比如我就写过
//want [4,1,2,3]
arr = [1,2,3].unshift(4)
//result
arr = 4
这个解决办法有很多,我常使用展开扩展符.
let arr = [1,2,3]
arr = [4,...arr]
filter内部是浅拷贝
这又是一个神奇的bug。看代码
// list = [{type:1},{type:2}]
const list = this.$store.state.list
.filter(e=>e.type === 1)
.map(e=>{
e.type=2
return e
})
本质上state.list是一个数组,内部元素都是对象。而我希望得到一个新数组。 运行完这段代码,你会发现state.list内部的值改变了。
**因为 filter本质上是浅拷贝,内部元素引用没有变
这里需要这样修改
const list = this.$store.state.list
.filter(e=>e.type === 1)
.map(e=>{
return {...e,type:2}
})
大家对于日常使用数组还发现有什么问题吗,欢迎留言讨论