diff --git a/publish/changeLog.md b/publish/changeLog.md index fbce380..f0bc6d1 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -1,6 +1,7 @@ ### 优化 - 缓冲进度条颜色 +- 优化数据存储,若需要存储的数据过大时会将数据切片后存储,现在存储大列表不会导致列表丢失了 ### 修复 diff --git a/src/plugins/storage.js b/src/plugins/storage.js index 72d9648..c4ad71e 100644 --- a/src/plugins/storage.js +++ b/src/plugins/storage.js @@ -1,8 +1,38 @@ 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) => { + const datas = [] + buildData(key, value, datas) + try { - await AsyncStorage.setItem(key, JSON.stringify(value)) + await AsyncStorage.multiSet(datas) } catch (e) { // saving error console.log(e.message) @@ -19,18 +49,40 @@ export const getData = async key => { console.log(e.message) throw e } - if (value) value = JSON.parse(value) + if (partKeyPrefixRxp.test(value)) { + return handleGetData(value) + } else if (value) value = JSON.parse(value) return value } export const removeData = async key => { + let value try { - await AsyncStorage.removeItem(key) + value = await AsyncStorage.getItem(key) } catch (e) { - // remove error + // error reading value console.log(e.message) 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() => { @@ -47,20 +99,34 @@ export const getAllKeys = async() => { } export const getDataMultiple = async keys => { - let values + let datas try { - values = await AsyncStorage.multiGet(keys) + datas = await AsyncStorage.multiGet(keys) } catch (e) { // read error console.log(e.message) 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 => { + const allData = [] + for (const [key, value] of datas) { + buildData(key, value, allData) + } try { - await AsyncStorage.multiSet(datas.map(({ key, value }) => ([key, JSON.stringify(value)]))) + await AsyncStorage.multiSet(allData) } catch (e) { // save error console.log(e.message) @@ -71,8 +137,16 @@ export const setDataMultiple = async datas => { export const removeDataMultiple = async keys => { 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 { - await AsyncStorage.multiRemove(keys) + await AsyncStorage.multiRemove(allKeys) } catch (e) { // remove error console.log(e.message)