小程序中缓存的正确使用

互联网 2022/5/13 17:21:06

小程序提供了诸多的接口用于保存本地缓存数据,有点类似 localstorage 的使用。现在利用缓存实现一个搜索记录的功能。 功能不复杂,但有几个点需要考虑: 1、缓存有上限,只保存最近搜索的20条记录,多出没有必要,且页面显示不全; 2、需要保证数据的唯一性;若搜索内容…

小程序提供了诸多的接口用于保存本地缓存数据,有点类似 localstorage 的使用。现在利用缓存实现一个搜索记录的功能。

 

 

 功能不复杂,但有几个点需要考虑:

1、缓存有上限,只保存最近搜索的20条记录,多出没有必要,且页面显示不全;

2、需要保证数据的唯一性;若搜索内容相同,后面的搜索内容应该覆盖前面的记录;

3、提供增删查的接口。

于是封装之后的实现如下:

class Record {
    constructor() {
        this.limitSize = 20;
        this.tag = 'word'
    }

    wordExist(word) {
        let all = this.getAllRecord();
        if(!all.length) return false;
        let element = all.find(item => item.word === word);
        return element ? element.key : false;
    }

    // 历史记录缓存, 使用同步接口
    setRecord(word = '') {
        try {
            // 重复的记录保证顺序,先删除之前的,再插入最新的。
            let key = this.wordExist(word);
            if(key) {
                this.removeRecordByKey(key);
            }
            wx.setStorage({
                key: this.tag + Date.now(),
                data: word
            })
        } catch (error) {
            console.log(error)
        }
    }

    getWordByKey(key = '') {
        try {
            let word = wx.getStorageSync(key);
            return word;
        } catch (error) {
            console.log(error);
        }
    }

    getAllRecord() {
        try {
            const res = wx.getStorageInfoSync();
            res.keys = res.keys.length ? res.keys.filter( i => i.includes(this.tag)) : [];
            if(!res.keys.length) return [];
            return res.keys.map(item => {
                return {
                    key: item,
                    word: this.getWordByKey(item)
                }
            })
        } catch (e) {
            console.log(e);
        }
    }

    removeRecordByKey(key) {
        try {
            wx.removeStorageSync(key);
        } catch (error) {
            console.log(error)
        }
    }

    // 删除所有历史记录
    clearAllReacord() {
        try {
            let record = this.getAllRecord();
            if(record.length) {
                record.forEach(item => {
                    wx.removeStorageSync(item.key)
                })
            }
        } catch (error) {
            console.log(error);
        }
    }
}

export default Record;

为什么会这样乱,是因为接口使用的诸多不便:

1、微信没有返回全部数据的接口,只有获取所有数据 key 的接口 getStorageInfoSync,想要获取所有的键值对,只能先获取key的集合,再遍历 key获取 value。

2、由于数据相同的key 会覆盖掉原来该 key 对应的内容,所以要保证key的唯一性,又由于本地保存的还有其他页面的数据,这里使用字符串 'word' + 时间戳保证数据的唯一性和数据页面的从属关系。

3、插入数据之前,先要判断是否已经存在和是否已经超限。可以看到为了实现逻辑,基本调用了所有数据缓存的接口,所以插入数据是一个非常耗费性能的操作。

思考:

1、代码乱是接口不满足要求,需要变通去实现对应的功能。如果直接有get方法返回所有数据,或者自动覆盖前面的数据,可以降低复杂程度;

2、仔细思考功能,数据唯一、容量限制、自动覆盖,实际上这是一个“队列”,结合上述可以实现这样一个特殊的队列,既可以规避频繁的读写本地数据,又可以简化逻辑。只需要在页面卸载的时候,将所有数据打包写入缓存即可。

class Queue {
    constructor() {
        this.limit = 20;

        let words = wx.getStorageSync('words');
        if (words) {
            this.words = JSON.parse(words);  // 取出缓存数据
        } else {
            this.words = [];
        }
    }

    getAll() {
        return this.words;
    }

    clearAll() {
        this.words = [];
    }

    get(index) {
        return this.words[index];
    }

    remove(index) {
        return this.words.splice(index, 1);
    }

    set(element) {
        // 判断是否超容
        let length = this.words.length;
        if (length > this.limit) {
            this.words.shift();
        }
        // 判断是否重复
        let index = this.words.indexOf(element);
        if (index !== -1) {
            this.words.splice(index, 1);  //保证顺序
        }
        this.words.push(element);
    }

    stringify() {
        try {
            wx.setStorageSync('key', JSON.stringify(this.words));
        } catch (e) {
            console.log(e);
        }
    }

}

export default Queue;

使用 Array 作为内部数据维护,相关的方法一应俱全,实现简单。

 

随时随地学软件编程-关注百度小程序和微信小程序
关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。
本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。
[小程序中缓存的正确使用]http://www.zyiz.net/tech/detail-320665.html

赞(0)
关注微信小程序
程序员编程王-随时随地学编程

扫描二维码或查找【程序员编程王】

可以随时随地学编程啦!

技术文章导航 更多>