const log = console.log
console.clear();
; (function (local) {
function isEmptyObject(e) {
for (let t in e) {
if (e.hasOwnProperty(t)) {
return false
}
}
return true
}
local.Storage.prototype['setObj'] = function (key, val) {
if (!isEmptyObject(key)) {
this.setItem(key, JSON.stringify(val))
}
}
local.Storage.prototype['getObj'] = function (key) {
if (this.hasObj(key)) {
return JSON.parse(this.getItem(key))
} else {
return null
}
}
local.Storage.prototype['hasObj'] = function (key) {
let result = this.getItem(key)
return !isEmptyObject(result)
}
class CacheManager {
static setSessionObj(key, val) {
log('设置缓存', key, val)
return sessionStorage.setObj(key, val)
}
static getSessionObj(key) {
let result = sessionStorage.getObj(key)
log('取出缓存', key, result)
return result
}
static hasSessionObj(key) {
let result = sessionStorage.getItem(key)
log('命中缓存', key, result, result !== '"WAITING_FOR_RESPONSE"')
return result && result !== '"WAITING_FOR_RESPONSE"'
}
static isWaitingForResponse(key) {
let result = sessionStorage.getItem(key)
log('等待缓存', key, result)
return result === '"WAITING_FOR_RESPONSE"'
}
}
window.CacheManager = CacheManager
})(window)
class Timer {
static loop(cb, delay = 3000) {
let timer = setInterval(() => cb(timer), delay)
}
}
class Interceptor {
list = {
request: [],
response: []
}
constructor(dispatchRequest) {
this.dispatchRequest = dispatchRequest
}
before(fulfield, reject) {
this.list.request.push(fulfield, reject)
}
after(fulfield, reject) {
this.list.response.push(fulfield, reject)
}
create(config) {
const chain = [
...this.list.request,
...[this.dispatchRequest, undefined],
...this.list.response
]
let promise = Promise.resolve(config)
while (chain.length) {
promise = promise.then(chain.shift(), chain.shift())
}
return promise
}
}
const ResponseInterceptor = [
response => {
if (response.isCache) {
return response
}
return response.json().then(data => {
CacheManager.setSessionObj(response.url, data)
return data
})
},
error => console.info(error)
]
class $Http {
static dispatchRequest(config) {
let url = config.baseUrl + config.url
if (CacheManager.isWaitingForResponse(url)) {
return new Promise(resolve => {
Timer.loop((timer) => {
log('waiting response...')
if (CacheManager.hasSessionObj(url)) {
resolve({ isCache: true, ...CacheManager.getSessionObj(url) })
clearInterval(timer)
}
})
})
} else if (CacheManager.hasSessionObj(url)) {
return { isCache: true, ...CacheManager.getSessionObj(url) }
}
CacheManager.setSessionObj(url, 'WAITING_FOR_RESPONSE')
return fetch(url, config)
}
static get(url, config) {
if (!this.interceptor) {
this.interceptor = new Interceptor($Http.dispatchRequest)
this.interceptor.after(...ResponseInterceptor)
}
return this.interceptor.create({ ...$Http.defaultConfig, ...config, url })
}
}
$Http.defaultConfig = {
baseUrl:
"https://mockapi.eolinker.com/mqWCWnNbac12467a9c069cba2af4929bbe2159af842804f/",
headers: {
mode: "cors"
}
}
; (async () => {
let result = await $Http.get("relogin")
log(result);
})()
$Http.get("relogin").then(result => log(result))
$Http.get("relogin").then(result => log(result))
console