SOURCE

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 命令行工具 X clear

                    
>
console