并发请求
- 方式1
- 比如一个下载页面,要发起10个请求才能获取全量数据,希望控制最多5个并发请求。
- 通过Promise.all、Promise.race进行控制
async function concurrentControl(poolLimit, requestPool) {
const ret = [];
const executing = [];
while (requestPool.length > 0) {
const request = requestPool.shift();
const p = Promise.resolve().then(() => request());
ret.push(p);
const e = p.then(() => executing.splice(executing.indexOf(e), 1));
executing.push(e);
if (executing.length >= poolLimit) {
await Promise.race(executing);
}
}
return Promise.all(ret);
}
function multiRequest(request = [], maxNum) {
const len = request.length;
const result = Array.from({ length: len }, (_, index) => false);
let count = 0;
return new Promise((resolve, reject) => {
while (count < maxNum) {
next();
}
function next() {
let current = count++;
if (current >= len) {
!result.includes(false) && resolve(result);
return;
}
const req = request[current];
req()
.then((res) => {
result[current] = res;
if (current < len) {
next();
}
})
.catch((err) => {
result[current] = err;
reject(result)
});
}
});
}
丢弃请求
useEffect(() => {
let didCancel = false;
const fetchData = async () => {
const result = await getData(query);
if (!didCancel) {
setResult(result);
}
}
fetchData();
return () => {
didCancel = true;
}
}, [query]);
function latestReq() {
let last;
function request(params) {
axios.then(() => {
if (last !== params) {
}
})
last = params;
}
return request;
}
淘汰请求
- 短时间内发送多个请求,而且前面发出的请求结果不能覆盖后面的(网络阻塞可能导致先发出的请求后返回)
let seqenceId = 0;
let lastId = 0;
function App() {
const [query, setQuery] = useState('react');
const [result, setResult] = useState();
useEffect(() => {
const fetchData = async () => {
const curId = ++seqenceId;
const result = await getData(query);
if (curId > lastId) {
setResult(result);
lastId = curId;
} else {
console.log(`discard ${result}`);
fetchData();
}, [query]);
return (
...
);
}
串行请求
详情
node 回调风格
详情
高优先级和低优先级请求
- 低优先级任务执行时机
- 定时器四秒后
- 遇到滑动、点击等事件时立即调用(通过发布订阅实现)
- 高优先级任务完成后调用
import axios from 'axios';
const requestQueue = [];
const HIGH_PRIORITY_REQUEST = '/high-priority-endpoint';
axios.interceptors.request.use(config => {
if (config.url === HIGH_PRIORITY_REQUEST) {
return config;
} else {
return new Promise(resolve => {
requestQueue.push(() => resolve(config));
});
}
});
axios.interceptors.response.use(response => {
if (response.config.url === HIGH_PRIORITY_REQUEST) {
requestQueue.forEach(executeRequest => executeRequest());
requestQueue.length = 0;
}
return response;
}, error => {
return Promise.reject(error);
});
function sendRequest(config) {
axios(config).then(response => {
console.log('请求成功:', response);
}).catch(error => {
console.log('请求失败:', error);
});
}
sendRequest({ url: HIGH_PRIORITY_REQUEST });
sendRequest({ url: '/normal-priority-endpoint-1' });
sendRequest({ url: '/normal-priority-endpoint-2' });