面试题答案
一键面试请求队列管理
- 原理:将多个请求按顺序排队处理,避免同时发起过多请求导致网络资源耗尽。
- 实现方法:使用队列数据结构(如数组)存储待发送的请求,通过一个函数按顺序依次处理队列中的请求。
const requestQueue = [];
function enqueueRequest(request) {
requestQueue.push(request);
if (requestQueue.length === 1) {
processQueue();
}
}
async function processQueue() {
while (requestQueue.length > 0) {
const request = requestQueue.shift();
try {
await fetch(request);
} catch (error) {
console.error('Request error:', error);
}
}
}
缓存策略
- 原理:对已请求的数据进行缓存,当再次请求相同数据时,直接从缓存中获取,减少网络请求次数。
- 实现方法:使用对象来存储缓存数据,以请求URL作为键,请求结果作为值。
const cache = {};
async function fetchWithCache(url) {
if (cache[url]) {
return cache[url];
}
const response = await fetch(url);
const data = await response.json();
cache[url] = data;
return data;
}
节流与防抖的应用
- 节流
- 原理:规定在一个单位时间内,只能触发一次请求。在高并发场景下,可限制请求频率,避免短时间内过多请求。
- 实现方法:使用
setTimeout
记录上次请求时间,在规定时间内忽略后续请求。
function throttle(func, delay) {
let lastCallTime = 0;
return function() {
const now = new Date().getTime();
if (now - lastCallTime >= delay) {
func.apply(this, arguments);
lastCallTime = now;
}
};
}
const throttledFetch = throttle(() => {
// 发起fetch请求
}, 1000);
- 防抖
- 原理:在一定时间内,如果再次触发请求,则重新计时,直到计时结束才真正发起请求。适用于用户频繁操作触发请求的场景,如搜索框输入时的搜索请求。
- 实现方法:使用
clearTimeout
和setTimeout
控制请求的延迟触发。
function debounce(func, delay) {
let timer;
return function() {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, arguments);
}, delay);
};
}
const debouncedFetch = debounce(() => {
// 发起fetch请求
}, 500);
处理竞态条件及确保数据一致性
- 处理竞态条件
- 原理:多个请求可能同时更新同一数据,导致数据不一致。通过加锁机制或使用Promise.allSettled确保所有相关请求完成后再处理结果。
- 实现方法:
- 加锁机制:使用一个标志变量表示是否正在处理请求,在请求开始时设置为true,结束时设置为false。
let isFetching = false;
async function safeFetch() {
if (isFetching) {
// 等待当前请求完成或采取其他处理方式
return;
}
isFetching = true;
try {
const response = await fetch('/api/data');
// 处理响应
} catch (error) {
console.error('Fetch error:', error);
} finally {
isFetching = false;
}
}
- **Promise.allSettled**:当多个组件发起请求影响同一数据时,使用`Promise.allSettled`等待所有请求完成,然后统一处理结果。
const requests = [fetch('/api/data1'), fetch('/api/data2')];
Promise.allSettled(requests).then(results => {
// 统一处理所有请求结果
results.forEach(result => {
if (result.status === 'fulfilled') {
// 处理成功结果
} else {
// 处理失败结果
}
});
});
- 确保数据一致性
- 原理:在数据更新时,采用版本控制或乐观锁机制,确保更新的数据是最新的。
- 实现方法:
- 版本控制:每次数据更新时,版本号加1。在请求数据时,带上当前版本号,服务器返回数据时也带上版本号。更新数据时,对比版本号,若不一致则重新获取最新数据再更新。
- 乐观锁:类似版本控制,在数据更新时,服务器检查数据是否被其他请求修改,若已修改则返回错误,客户端重新获取数据后再尝试更新。
在Vue项目中,可以将上述优化逻辑封装成可复用的函数或插件,在需要发起fetch
请求的组件中引入使用,以提升高并发场景下的性能和数据一致性。