前端轮训降级方案

本文介绍了一种前端定时任务的保护方案,通过设置3次错误尝试,当函数执行失败时,逐步增加执行间隔,直至恢复正常周期。设计包括熔断逻辑、替代原生setInterval的方法和代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

副标题

前端定时任务的自我保护

需求背景

前端setInterval会持续定时的执行一段任务,具体的api如下

setInterval(function, milliseconds, param1, param2, ...)

希望在function失败时,有一个机制可以减少任务执行,或者不执行。

设计方案

  1. 代替原生setInterval
  2. 允许3次错误尝试
  3. 3次错误尝试后,阶梯自增milliseconds
  4. 正确访问后,回到初始milliseconds

流程图

设计流程图

代码逻辑

/**
 * @description 轮询熔断
 * 1. 代替原生setInterval
 * 2. 错误尝试
 * 3. 阶梯递增时间周期
 * 4. 正确访问后,降低时间周期至原始周期
 */

/**
 * 使用方式
 * @param callback 定时器执行的函数
 * @param interval 定时器周期 毫秒数
 * @returns timerId 定时器id,调用方可以手动关闭定时器
 * fuseInterval(callback, interval)
 */

export default class FuseInterval {
  step = 0 // 阶段

  stage = [] // 存储定时周期,以2x,5x,10倍为单位

  interval = null // 执行周期

  callback = null // 定时到期,需要执行的函数

  timeId = null // 当前定时器id

  errorTimes = 0 // 失败次数

  maxErrorTimes = 3 // 最大失败次数

  constructor(callback, interval) {
    // 可以根据自己的需求修改重试周期
    this.stage = [interval * 2, interval * 5, interval * 10, interval * 20]
    this.callback = callback
  }

  // 定时任务
  setInterval() {
    this.timeId = setInterval(async () => {
      try {
        await this.callback()
        this.errorTimes = 0
        // 如果请求成功,错误尝试重置为0
        if (this.step > 0) {
          this.step = 0
          clearInterval(this.timeId)
          return this.setInterval()
        }
        return this.timeId
      } catch (error) {
        // 判断是否超过单周期的最大请求次数
        if (this.errorTimes > this.maxErrorTimes) {
          // 清除定时器,step++,errorTimes赋值为0,开始新的需求
          clearInterval(this.timeId)
          this.errorTimes = 0
          this.step++
          return this.setInterval()
        }
        // 判断是否超过最大周期阈值
        if (this.step > this.stage.length) {
          clearInterval(this.timeId)
          this.step = 0
          this.errorTimes = 0
          return this.timeId
        }
        this.errorTimes++
        return this.timeId
      }
    }, this.stage[this.step])
  }
}

// 调用方
const fuseInterval = new FuseInterval(async () => {
 try {
    return await this.task()
  } catch (error) {
    return Promise.reject(error)
  }
}, 2 * 1000)
this.timer = fuseInterval.setInterval() // 返回一个定时器,给到调用方使用

更新记录:

  1. 同事纠正,熔断是立即行为。这个属于降级方案。故改下名字
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值