背景原因
因为项目中A数据过于庞大,每次请求时间较长,为了减少对A数据的请求,也为了保证项目中所用到的A数据是同一份数据。
什么是单例模式
单例模式就是保证一个类仅有一个实例,并提供一个访问它的全局访问点。
单例模式实现
class ShopInfoData {
constructor() {
this.shopData = [];
}
async get() {
return this.shopData;
}
}
ShopInfoData.getInstance = (function() {
let instance;
return function() {
if (!instance) {
instance = new ShopInfoData();
}
return instance;
};
})();
获取常量的数据可以通过上述方式过去,那怎么从接口获取数据呢???
class ShopInfoData {
constructor() {
this.shopData = [];
this.count = 1;
}
async get() {
if (!this.shopData.length) {
await this.refresh();
}
return this.shopData;
}
// 获取数据
async refresh() {
await new Promise(resolve => {
setTimeout(() => {
console.log('进来了多少次')
this.shopData = [this.count++];
resolve(this.count)
}, 1000);
});
}
}
ShopInfoData.getInstance = (function() {
let instance;
return function() {
if (!instance) {
instance = new ShopInfoData();
}
return instance;
};
})();
通过上述代码已经实现异步获取数据的单例,后续使用的数据也是同一份且不会多次请求数据进行更新。
你以为功能完成了,万事大吉了么? 不不不,初始化获取实例时还是会多次调用refresh函数,和直调用一次有冲突,这就是单例模式出现竞争状态导致的
class ShopInfoData {
constructor() {
this.shopData = [];
this.pendingPromise;
}
async get() {
if (!this.shopData.length) {
await this.refresh();
} else {
return this.shopData;
}
return this.pendingPromise.then(res => {
return this.shopData;
});
}
// 获取数据
async refresh() {
if (!this.pendingPromise) {
this.pendingPromise = new Promise(resolve => {
setTimeout(() => {
console.log('进来了多少次')
this.shopData = [1];
resolve(1);
}, 1000);
});
}
return this.pendingPromise;
}
// 需要重新获取数据的时候重置pendingPromise
async refreshAndGet(sourceFilters, statusFilters, showNoShop = false) {
// 重置pendingPromise,会重新请求接口
this.pendingPromise = undefined;
return this.get();
}
}
ShopInfoData.getInstance = (function() {
let instance;
return function() {
if (!instance) {
instance = new ShopInfoData();
}
return instance;
};
})();
到此,就结束了!!!