优化数据存储,若需要存储的数据过大时会将数据切片后存储,现在存储大列表不会导致列表丢失了

This commit is contained in:
lyswhut 2021-09-26 16:31:27 +08:00
parent 5cbaca8395
commit a341c05a7f
2 changed files with 84 additions and 9 deletions

View File

@ -1,6 +1,7 @@
### 优化 ### 优化
- 缓冲进度条颜色 - 缓冲进度条颜色
- 优化数据存储,若需要存储的数据过大时会将数据切片后存储,现在存储大列表不会导致列表丢失了
### 修复 ### 修复

View File

@ -1,8 +1,38 @@
import AsyncStorage from '@react-native-async-storage/async-storage' import AsyncStorage from '@react-native-async-storage/async-storage'
const partKeyPrefix = '@___PART___'
const partKeyPrefixRxp = /^@___PART___/
const keySplit = ','
const limit = 500000
const buildData = (key, value, datas) => {
let valueStr = JSON.stringify(value)
if (valueStr.length <= limit) return datas.push([key, valueStr])
const partKeys = []
for (let i = 0, len = Math.floor(valueStr.length / limit); i <= len; i++) {
let partKey = `${partKeyPrefix}${key}${i}`
partKeys.push(partKey)
datas.push([partKey, valueStr.substring(i * limit, (i + 1) * limit)])
}
datas.push([key, `${partKeyPrefix}${partKeys.join(keySplit)}`])
return datas
}
const handleGetData = partKeys => {
partKeys = partKeys.replace(partKeyPrefixRxp, '').split(keySplit)
return AsyncStorage.multiGet(partKeys).then(datas => {
return JSON.parse(datas.map(data => data[1]).join(''))
})
}
export const setData = async(key, value) => { export const setData = async(key, value) => {
const datas = []
buildData(key, value, datas)
try { try {
await AsyncStorage.setItem(key, JSON.stringify(value)) await AsyncStorage.multiSet(datas)
} catch (e) { } catch (e) {
// saving error // saving error
console.log(e.message) console.log(e.message)
@ -19,18 +49,40 @@ export const getData = async key => {
console.log(e.message) console.log(e.message)
throw e throw e
} }
if (value) value = JSON.parse(value) if (partKeyPrefixRxp.test(value)) {
return handleGetData(value)
} else if (value) value = JSON.parse(value)
return value return value
} }
export const removeData = async key => { export const removeData = async key => {
let value
try { try {
await AsyncStorage.removeItem(key) value = await AsyncStorage.getItem(key)
} catch (e) { } catch (e) {
// remove error // error reading value
console.log(e.message) console.log(e.message)
throw e throw e
} }
if (partKeyPrefixRxp.test(value)) {
let partKeys = value.replace(partKeyPrefixRxp, '').split(keySplit)
partKeys.push(key)
try {
await AsyncStorage.multiRemove(partKeys)
} catch (e) {
// remove error
console.log(e.message)
throw e
}
} else {
try {
await AsyncStorage.removeItem(key)
} catch (e) {
// remove error
console.log(e.message)
throw e
}
}
} }
export const getAllKeys = async() => { export const getAllKeys = async() => {
@ -47,20 +99,34 @@ export const getAllKeys = async() => {
} }
export const getDataMultiple = async keys => { export const getDataMultiple = async keys => {
let values let datas
try { try {
values = await AsyncStorage.multiGet(keys) datas = await AsyncStorage.multiGet(keys)
} catch (e) { } catch (e) {
// read error // read error
console.log(e.message) console.log(e.message)
throw e throw e
} }
return values.map(([key, value]) => ({ key, value: JSON.parse(value) })) const promises = []
for (const data of datas) {
if (partKeyPrefixRxp.test(data[1])) {
promises.push(handleGetData(data[1]))
} else {
promises.push(Promise.resolve(data[1] ? JSON.parse(data[1]) : data[1]))
}
}
return Promise.all(promises).then(values => {
return datas.map(([key], index) => ({ key, value: values[index] }))
})
} }
export const setDataMultiple = async datas => { export const setDataMultiple = async datas => {
const allData = []
for (const [key, value] of datas) {
buildData(key, value, allData)
}
try { try {
await AsyncStorage.multiSet(datas.map(({ key, value }) => ([key, JSON.stringify(value)]))) await AsyncStorage.multiSet(allData)
} catch (e) { } catch (e) {
// save error // save error
console.log(e.message) console.log(e.message)
@ -71,8 +137,16 @@ export const setDataMultiple = async datas => {
export const removeDataMultiple = async keys => { export const removeDataMultiple = async keys => {
if (!keys.length) return if (!keys.length) return
const datas = await AsyncStorage.multiGet(keys)
let allKeys = []
for (const [key, value] of datas) {
allKeys.push(key)
if (partKeyPrefixRxp.test(value)) {
allKeys.push(...value.replace(partKeyPrefixRxp, '').split(keySplit))
}
}
try { try {
await AsyncStorage.multiRemove(keys) await AsyncStorage.multiRemove(allKeys)
} catch (e) { } catch (e) {
// remove error // remove error
console.log(e.message) console.log(e.message)