快手如何对请求进行缓存

# 快手如何对请求进行缓存

如何对请求进行缓存,例如有10个异步请求,如果有一个异步请求返回结果剩下的请求就用这个结果,并且能过传入成功和失败的回调函数

# 使用强缓存

表示在缓存期间不需要请求

可以通过设置HTTP Header 实现:

Expires

Cache-Control

# Expires

Expires是HTTP/1中的,表示资源在指定时间之后失效,需要重新请求

受限制与本地时间,可以通过修改本地时间导致其失效

// 2020-03-10 11:11:28 后失效,需要重新请求
res.setHeader('Expires','Tue Mar 10 2020 11:11:28 GMT+0800')
1
2

# Cache-Control

Cache-Control 出现于 HTTP/1.1,优先级高于 Expires

可以组合使用多种指令

// 10s后失效
 res.setHeader('Cache-control', 'max-age=10')
1
2

指令 作用

public 响应可以被服务端或者客户顿缓存

private 响应只可以被客户端缓存

max-age=30 缓存30s后过期需要重新请求

s-maxage=30 覆盖max-age,作用一致,代理服务器才生效

no-store 不缓存任何响应

no-cache 资源能被缓存,但立即失效

max-stale=30 30s内,即使缓存过期也使用该缓存

min-fresh=30 希望30s内获取最新的响应

# node为例

const http = require('http')

let server = http.createServer(async (req, res) => {
    //  -------跨域支持-----------
    // 放行指定域名
    res.setHeader('Access-Control-Allow-Origin', '*')
    //跨域允许的header类型
    res.setHeader("Access-Control-Allow-Headers", "*");

    let { method, url } = req
    if (method === 'OPTIONS') {
        return res.end()
    }
    console.log(method, url)
    if (url === '/api/expires') {
        // 设置过期时间
        res.setHeader('Expires', 'Tue Mar 10 2020 11:11:28 GMT+0800')
        return res.end(`Expires---${new Date()}`)
    }
    if (url === '/api/cache') {
        // 设置10s后过期,需重新请求
        res.setHeader('Cache-control', 'max-age=10')
        return res.end(`Cache-control---${new Date()}`)
    }
    res.end('success')
})

// 启动
server.listen(3000, err => {
    console.log(`listen 3000 success`);
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

Axios请求示例

<button id="cache">cache</button>
    <button id="expires">expires</button>
    <script>
        expires.addEventListener('click', function () {
            for (let i = 0; i < 10; i++) {
                axios.get('http://localhost:3000/api/expires')
                    .then(res => {
                        let { status, data } = res
                        console.log(status, data)
                    })
            }
        })

        cache.addEventListener('click', function () {
            for (let i = 0; i < 10; i++) {
                axios.get('http://localhost:3000/api/cache')
                    .then(res => {
                        let { status, data } = res
                        console.log(status, data)
                    })
            }
        })
    </script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

简单写下针对GET 请求进行缓存的就可以了吧,其他思路都差不多

function request(url, success, failure) {
    const cache = request.cache[url];
    let promise = null;
    if (!cache) {
        console.log('not cache');
        promise = fetch(url);
        request.cache[url] = promise;
    } else {
        console.log('cache');
        promise = request.cache[url];
    }
    console.log(promise);
    promise
        .then(res => {
            return res.clone().json()
        })
        .then(json => {
            success(json);
        })
        .catch(error => {
            failure(error);
        })
}
request.cache = {};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const promise1 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 500, 'one');
});

const promise2 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 100, 'two');
});


function getRaceApis(promiseArr){
    return new Promise(function(resolve, reject) {
        try {
            Promise.race(promiseArr).then(function(value) {
                return Promise.allSettled(promiseArr).
                then((results) => results.forEach((result) => console.log(value)));
                // Both resolve, but promise2 is faster
            })
        } catch(err) {
            reject(err)
        }
    });
}


getRaceApis([promise1, promise2]).then((result) => {console.info(result)})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
上次更新: 2022/8/26 下午8:00:44