封装原因: localStorage 线程不安全,set和get直接会有500ms的延迟
1.store.js文件
// 1. 可以自选,我是不是要本地存储 localStorage 或者是 sessionStorage
// param1: unLocal, 默认是false, 即在本地浏览器中存储
const CreateStore = function(unLocal = false, maxLength = 30) {
this.unLocal = unLocal;
this.maxLength = maxLength;
this.observe();
};
CreateStore.prototype.set = function(type, data) {
this.__mock__storage[`${this.storeKey}_${type}`] = data;
};
CreateStore.prototype.get = function(type) {
return this.__mock__storage[`${this.storeKey}_${type}`];
};
CreateStore.prototype.observe = function() {
const context = this;
this.__mock__storage = new Proxy(
{},
{
get(target, propKey, receiver) {
let result;
if(!context.unlocal) {
// 如果你选用了本地存储的方式,我直接给你getItem
result = (context.getItem && context.getItem(propKey)) || void 0;
}
return result || Reflect.get(target, propKey, receiver);
},
set(target, propKey, value, receiver) {
let _value = value;
// 数组要劫持
if(value instanceof Array && value.length > context.maxLength) {
_value = value.slice(0, context.maxLength);
};
// 如果说,unLocal === false, 意味着,我们要在一个合适的时间
// 进行本地的存储
if(!context.unlocal) {
new Promise((resolve) => {
resolve(0)
}).then(() => {
context.setItem && context.setItem(propKey, _value);
})
}
return Reflect.set(target, propKey, value, receiver);
}
}
)
};
CreateStore.prototype.setItem = function(type, data) {
if(!window) throw new Error('browser runtime need');
const dataJson = JSON.stringify(data);
window[this.storageMethod].setItem(type, dataJson);
};
CreateStore.prototype.getItem = function(type) {
if(!window) throw new Error('browser runtime need');
const data = window[this.storageMethod].getItem(type);
let dataJson;
try {
dataJson = JSON.parse(data);
} catch (err) {
throw new Error(err);
}
return dataJson;
};
['pop', 'push', 'unshift', 'shift', 'reverse', 'splice'].forEach((method) => {
CreateStore.prototype[method] = function(type, ...rest) {
// 如果你没有,你要用数组方法,那我给你整个空数组
if(!this.get(type)) {
this.set(type, []);
};
// 如果你有,但你不是数组,拜拜~
if(!this.get(type) instanceof Array) {
throw new Error('this data using array methods must be an array');
};
// 拿数组数据了
const dataList = this.get(type);
Array.prototype[method].apply(dataList, rest);
this.set(type, dataList);
}
});
// rest, 就是 CreateStore 的参数
const CreateLocalStore = function(key, ...rest) {
// 构造函数继承
CreateStore.apply(this, rest);
// 我要有一个关键词,作为我实际调用的时候,到底是 window.localStorage 还是 sessionStorage
this.storageMethod = 'localStorage';
this.storeKey = `LOCAL_KEY_${key}`;
};
function inherit(Father) {
if(Object.create) return Object.create(Father.prototype);
const Fn = function() {};
Fn.prototype = Father.prototype;
return new Fn();
}
CreateLocalStore.prototype = inherit(CreateStore);
CreateLocalStore.prototype.constructor = CreateLocalStore;
const CreateSessionStore = function(key, ...rest) {
// 构造函数继承
CreateStore.apply(this, rest);
this.storageMethod = 'sessionStorage';
this.storeKey = `SESSION_KEY_${key}`;
}
CreateSessionStore.prototype = inherit(CreateStore);
CreateSessionStore.prototype.constructor = CreateSessionStore;
export const localStore = new CreateLocalStore('demo');
export const sessionStore = new CreateLocalStore('demo', false);
使用方式:
localStore.set('history', []);
localStore.pop('history', "msg1");
localStore.push('history', "msg2");