sunnylqm / react-native-storage

local storage wrapper for both react-native and browser. Support size controlling, auto expiring, remote data auto syncing and getting batch data in one query.
MIT License
3.02k stars 268 forks source link

数据数量超过size后,不会循环覆盖,直接调不出 #180

Open alansuhe opened 6 years ago

alansuhe commented 6 years ago

但如果size上限很小,如3,则超过数量,也不会循环覆盖,而是继续存储。 catch不到任何报错

sunnylqm commented 6 years ago

贴代码

alansuhe commented 6 years ago

第一个页面,初始化

const storage = new Storage({
    // 最大容量,默认值1000条数据循环存储
    size: 100,

    // 存储引擎:对于RN使用AsyncStorage,对于web使用window.localStorage
    // 如果不指定则数据只会保存在内存中,重启后即丢失
    storageBackend: AsyncStorage,

    // 数据过期时间,默认一整天(1000 * 3600 * 24 毫秒),设为null则永不过期
    //defaultExpires: 1000 * 3600 * 24,
    defaultExpires: null,

    // 读写时在内存中缓存数据。默认启用。
    enableCache: true,
});
componentDidMount() {
        global.storage = storage;
    }

调用方法:

/**
     * storage
     */

    refreshData = ()=> {
        // 获取某个key下的所有id(仅key-id数据)
        storage.getIdsForKey(consts.STORAGE_NAME).then(ids => {
            console.log(ids);
        });
        //console.log("----refresh");
        // 获取某个key下的所有数据(仅key-id数据)
        //this.setState({isLoading: true});
        storage.getAllDataForKey(consts.STORAGE_NAME).then(data  => {
            //console.log(data);
            //this.setState({data});//.filter(item => item.uploadImageSource)
            this.setState({
                //isLoading: false,
                data: data.reverse()//倒序
            })
        }).catch(err => {
            //this.setState({isLoading: false});
            // 如果没有找到数据且没有sync方法,
            // 或者有其他异常,则在catch中返回
            // console.warn("storage err", err.message);
            switch (err.name) {
                case 'NotFoundError'://没找到
                    // TODO;
                    break;
                case 'ExpiredError'://过期
                    // TODO
                    break;
            }
        });
    }

写入数据:

/**
     * 本地存储
     */
    saveToStore(){
        const date = new Date();
        const dateStamp = Date.parse(date);
        const result = {
            hgResultArr: this.state.hgResultArr,
            hg: this.state.hg,
            questionTypeIndex: this.state.questionTypeIndex,
            question: this.state.question,
            time: date,
            result_id: dateStamp
        };

        //console.log('timestamp', Date.parse(result.time))

        storage.save({
            key: consts.STORAGE_NAME,  // 注意:请不要在key中使用_下划线符号!
            id: dateStamp,   // 注意:请不要在id中使用_下划线符号!
            data: result,
            //expires: 1000 * 60
        });

    }
alansuhe commented 6 years ago

@sunnylqm 这几天没来得及回应见谅

sunnylqm commented 6 years ago

所以是哪里结果不符合预期?

alansuhe commented 6 years ago

以IOS为例: 预期是设定一个上限,超过后,自动循环删除最老的,新记录仍然可以写入。 实际: 1、测试环境,设定一个上限值(如5),超过后仍可以不断存入,没有受到上限限制; 2、正式发布的,上限设置较大(几百),到了总数超过限度,就一个数据也读不出了(getAllDataForKey),而且新的也再也写不进去; 第二种情况,在测试环境没碰到,因为没测这么大量。

sunnylqm commented 6 years ago

1、测试环境,设定一个上限值(如5),超过后仍可以不断存入,没有受到上限限制; —— 这符合预期啊 2、什么叫读不出和写不进去?

alansuhe commented 6 years ago

1、测试环境,设定一个上限值(如5),超过后仍可以不断存入,没有受到上限限制; —— 这符合预期啊

可能我没说清楚,预期是存入后,总数最多是5,原来最早的数据被循环删除了,现在没有删除,总数还在不断上升。

2、什么叫读不出和写不进去? 在这个场景,数据消失了,无法读取到,而且在执行写入后,仍然无法读取。

sunnylqm commented 6 years ago

1、能给一段最小重现的代码吗 2、这种描述还是没有区别,我还是得接着问,什么叫做消失,什么叫做无法读取?——请直接说有什么具体输出结果?有什么具体报错?

alansuhe commented 6 years ago

1、 初始化

const storage = new Storage({
    size: 5, 
    storageBackend: AsyncStorage,
    defaultExpires: null,
    enableCache: true,
});
// ....
componentDidMount() {
        global.storage = storage;
    }

然后,写入方法:

   saveToStore(){
        const date = new Date();
        const dateStamp = Date.parse(date);
        const result = {
            //...数据内容省略
        };
        storage.save({
            key: “TEST_KEY”
            id: dateStamp,  
            data: result,
        });
    }

反复执行写入,同时监控总数,

storage.getAllDataForKey(“TEST_KEY”).then(all  => {
            console.log(all.length)
        })

期待当写入数超过5时,读出总数稳定在上限5不变,但实际仍然增长。

2、这个问题只有数量较大,还需要iphone真机才能再现,我再观察一下吧。

sunnylqm commented 6 years ago

感谢反馈,我稍后看一下

alansuhe commented 6 years ago

今天我又试了一次,把整个项目升级成react native 0.56,其他代码均不变。 这次在模拟器上,不管size设置多大,只要总数超过size的定义,用storage.getAllDataForKey方法就读取不到数据。报错信息:

Not Found! Params: {"key":"hg-result","id":1531294322000,"autoSync":true,"syncInBackground":true}

其中id是最后一条写入的数据。

之后storage.save方法执行写入其他数据后,再读取始终报同样错误,id也是一样,应该没有写入成功; 这时我用storage.clearMapForKey方法清除key下的数据,无效,再写入读取,也报同样错(id一样); 最后用storage.clearMap方法清除所有数据,再写入,可以读取正常了,直到size超过继续上述错误。

NrqhEIcsRi004 commented 5 years ago

同样的问题

sunnylqm commented 5 years ago

写了段单元测试,未能重现 https://github.com/sunnylqm/react-native-storage/blob/master/__tests__/basic-function-test.js#L236

NrqhEIcsRi004 commented 5 years ago

@sunnylqm 是不是我们用的版本的问题?我们用的 1.0.0-beta.1

sunnylqm commented 5 years ago

@NrqhEIcsRi004 单元测试也是测的这个版本