在 javascript 中实现接口请求的熔断降级,核心思路是维护一个基于时间窗口的错误计数器,当单位时间内失败次数超过阈值时,自动切断后续请求并返回预设的降级数据。具体做法是封装一个拦截器或高阶函数,在每次 fetch 调用后检查响应状态,若成功则重置计数器,若失败则累加计数;一旦触发熔断,立即跳过网络请求并执行降级逻辑。

如何设计熔断器的状态机与判断逻辑
熔断器通常包含三个状态:关闭(Closed)、打开(Open)和半开(Half-Open)。关闭状态下允许请求通过,但需记录错误;打开状态下直接拒绝请求并执行降级;半开状态用于测试服务是否恢复。判断逻辑依赖于当前时间与上次熔断时间的差值,以及滑动窗口内的错误率。

class CircuitBreaker {
constructor(options = {}) {
this.errorThreshold = options.errorThreshold || 5;
this.timeout = options.timeout || 60000;
this.state = 'CLOSED';
this.errorCount = 0;
this.lastFailureTime = null;
}
async execute(fn, fallback) {
if (this.state === 'OPEN') {
const now = Date.now();
if (now - this.lastFailureTime > this.timeout) {
this.state = 'HALF_OPEN';
} else {
return fallback();
}
}
try {
const result = await fn();
this.onSuccess();
return result;
} catch (error) {
this.onError();
return fallback(error);
}
}
onSuccess() {
this.errorCount = 0;
this.state = 'CLOSED';
}
onError() {
this.errorCount++;
this.lastFailureTime = Date.now();
if (this.errorCount >= this.errorThreshold) {
this.state = 'OPEN';
}
}
}
// 使用示例
const breaker = new CircuitBreaker({ errorThreshold: 3, timeout: 10000 });
const data = await breaker.execute(
() => fetch('/api/data').then(r => r.json()),
() => ({ cached: true, data: [] }) // 降级数据
);
如何在实际项目中集成 Fetch 拦截器
在实际项目中,可以通过重写全局 fetch 或使用 Axios 拦截器来统一处理熔断逻辑。这里展示如何在不修改业务代码的前提下,通过装饰器模式将熔断器注入到现有的请求流程中。关键在于捕获所有非 2xx 的状态码和网络异常,并将其传递给熔断器实例。

const originalFetch = window.fetch;
const circuitBreakers = new Map();
function getCircuitBreaker(url) {
if (!circuitBreakers.has(url)) {
circuitBreakers.set(url, new CircuitBreaker());
}
return circuitBreakers.get(url);
}
window.fetch = async function(...args) {
const url = args[0];
const breaker = getCircuitBreaker(url);
return breaker.execute(
() => originalFetch.apply(this, args),
(err) => {
console.warn('Circuit Open, using fallback for', url);
return Promise.resolve(new Response(JSON.stringify({ error: 'Service Unavailable' }), { status: 503 }));
}
);
};
// 业务代码无需改动
fetch('/api/users').then(res => res.json()).then(console.log);
当请求参数包含敏感字段时如何处理
当请求参数中包含敏感字段(如用户 ID 或 Token)时,熔断器不应将这些信息暴露在降级日志或缓存中。应在进入熔断器前对参数进行脱敏处理,或者在降级阶段仅返回通用的错误提示,而不携带任何原始请求上下文。这样可以防止在系统不稳定时泄露用户隐私。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











