前端面试场景题 1 (批量处理toast、减少if-else)
一、请求失败会弹出 一个toast , 如何保证批量请求失败 , 只弹出一个toast
方法一:使用全局标志位
JavaScript
let isToastShown = false; // 全局标志位
function makeRequests() {
const requests = [
fetchPost(),
fetchComments()
]; // 多个请求
Promise.all(requests)
.then(() => {
// 所有请求成功的处理逻辑
})
.catch(errors => {
if (!isToastShown) {
// 检查标志位
notify(errors[0]); // 弹出 toast
isToastShown = true; // 设置标志位为 true
}
});
}
function fetchJSON(url, input) {
return fetch(url, input)
.then(res => {
if (res.ok) {
return res.json();
}
const err = new HttpError(res);
if (!isToastShown) { // 检查标志位
notify(err); // 弹出 toast
isToastShown = true; // 设置标志位为 true
}
throw err; // 确保错误被抛出,否则后续逻辑可能无法捕获
});
}
// 示例错误类
class HttpError extends Error {
constructor(response) {
super(`${response.status} ${response.statusText}`);
this.name = "HttpError";
this.response = response;
}
}
// 重置标志位(在新的请求开始前)
makeRequests().finally(() => {
isToastShown = false; // 确保在下一次请求时标志位被重置
});
方法二:使用防抖函数
JavaScript
// 防抖函数
function debounce(fn, delay = 1000) {
let timeout;
return function (...args) {
clearTimeout(timeout);
timeout = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
const notifyDebounced = debounce(message => {
notify(message);
}, 3000); // 3 秒内只执行一次
// 示例调用
fetchJSON(url, input)
.catch(err => {
notifyDebounced(err); // 使用防抖后的通知函数
});
方法三:集中处理错误
JavaScript
function makeRequests() {
const requests = [
fetchPost(),
fetchComments()
]; // 多个请求
Promise.allSettled(requests)
.then(results => {
const hasError = results.some(result => result.status === "rejected");
if (hasError) {
const firstError = results.find(result => result.status === "rejected").reason;
notify(firstError); // 合并所有错误并只弹出一次
} else {
// 所有请求成功的处理逻辑
}
});
}
二、减少项目中的 if-else
语句
1. 策略模式
JavaScript
// 定义策略对象
const strategies = {
condition1: (arg) => {
// 处理条件 1 的逻辑
console.log(`Handling condition1 with argument: ${arg}`);
},
condition2: (arg) => {
// 处理条件 2 的逻辑
console.log(`Handling condition2 with argument: ${arg}`);
},
// 更多条件和处理逻辑
};
// 动态获取条件并执行策略
function handleCondition(condition, arg) {
const strategy = strategies[condition];
if (strategy) {
strategy(arg);
} else {
console.log(`Unknown condition: ${condition}`);
}
}
// 示例调用
handleCondition("condition1", "foo"); // 输出:Handling condition1 with argument: foo
handleCondition("condition3", "bar"); // 输出:Unknown condition: condition3
2. 表驱动法(动态条件)
JavaScript
const handlers = {
"condition1": (arg) => console.log(`Handling condition1 with ${arg}`),
"condition2": (arg) => console.log(`Handling condition2 with ${arg}`),
// 其他条件处理函数
};
function processConditions(conditions, arg) {
conditions.forEach(condition => {
const handler = handlers[condition];
handler && handler(arg);
});
}
// 示例调用
processConditions(["condition1", "condition2"], "data"); // 输出两个条件的处理结果
3. 提取函数
JavaScript
function handleCaseA() {
// 大量逻辑 A
}
function handleCaseB() {
// 大量逻辑 B
}
function main() {
const type = getType();
if (type === "A") {
handleCaseA();
} else if (type === "B") {
handleCaseB();
} else {
console.log("Unknown type");
}
}
4. 状态模式
JavaScript
// 定义状态类
class State {
handle(context) {
console.log("Default state handling");
}
}
class StateA extends State {
handle(context) {
console.log("Handling State A");
context.state = new StateB(); // 转换状态
}
}
class StateB extends State {
handle(context) {
console.log("Handling State B");
context.state = new StateA();
}
}
// 上下文对象
class Context {
constructor() {
this.state = new StateA();
}
request() {
this.state.handle(this);
}
}
// 示例调用
const context = new Context();
context.request(); // 输出:Handling State A
context.request(); // 输出:Handling State B
总结
-
全局标志位:适用于简单的单次通知场景。
-
防抖节流:适用于需要限制通知频率的场景。
-
集中处理错误:适用于批量请求的错误统一管理。
-
策略模式/表驱动法:将条件逻辑抽离为独立模块,增强可维护性。
-
状态模式:适用于对象状态频繁变化的场景。