zoukankan      html  css  js  c++  java
  • 多个请求间断失败,如何优雅处理?

    背景

    试想这样一个场景:在访问系统的某个页面时,会发出多个请求,恰巧在某个时间点,登录信息过期了,这个时候需要自动跳转到登录页。由于请求返回的时间不一致,可能会多次执行跳转,造成使用困扰。

    问题核心

    法律常识告诉我,不能对同一行为进行多次评价。所以,我们也不能对同一错误进行多次处理。

    解决方案:发布订阅

    每次请求,可以订阅一次事件(譬如叫 logoutHandler),当一个请求出错则广播错误信息,那些订阅了这个事件的请求,就不再处理后续的响应了。伪代码如下:

    const PubSub = {}
    
    const request = opt => {
      let isErrorHandled = false
      PubSub.subscribe('logoutHandler', () => isErrorHandled = true)
    
      return fetch(opt)
        .catch(e => {
          if (isErrorHandled) throw null
    
          if (e.status === 'logout') {
            PubSub.publish('logoutHandler', e)
            // redirect to login page
          }
          throw null
        })
    }
    

    很好,解决了上面的问题。但,这样做会导致内存随请求的增加而线性增长。有没有更好的方案?

    解决方案:时间治愈一切

    在初始化过程中,设置一个起始时间戳。每次请求,再对该请求附加一个当前时间戳。当发现用户信息失效,则重置起始时间戳。根据时间的大小,决定是否处理错误信息。伪代码如下:

    let __startTime = Date.now()
    
    const request = opt => {
      const requestTime = Date.now()
    
      return fetch(opt)
        .catch(e => {
          const isErrorHandled = requestTime <= __startTime
          if (isErrorHandled) throw null
    
          if (e.status === 'logout') {
            __startTime = Date.now()
            // redirect to login page
          }
    
          throw null
        })
    }
    

    这种方式,无论是时间开销还是内存开销,都可以忽略不计。

    进一步优化

    当应用已经跳转到登录页了,即使之前的请求响应正常,其实也不需要再处理了。

    let __startTime = Date.now()
    
    const request = opt => {
      const requestTime = Date.now()
    
      return fetch(opt)
        .then(res => { // 新增:不再处理正常响应
          const isErrorHandled = requestTime <= __startTime
          if (isErrorHandled) throw null
    
          return res
        })
        .catch(e => {
          const isErrorHandled = requestTime <= __startTime
          if (isErrorHandled) throw null
    
          if (e.status === 'logout') {
            __startTime = Date.now()
            // redirect to login page
          }
    
          throw null
        })
    }
    
  • 相关阅读:
    css命名规范
    CSS3:box-sizing 怪异盒模型
    CSS3: box-shadow 阴影
    Spring boot分层和基本概念
    Spring boot异常统一处理方法:@ControllerAdvice注解的使用、全局异常捕获、自定义异常捕获
    Spring boot基础:配置文件配置变量、多环境的配置
    IDEA是如何导入项目的,及启动导入项目遇到的问题:无法加载主类的一连串问题
    创建spring boot项目启动报错遇到的问题
    详解Spring Boot集成MyBatis的开发流程
    spring boot常用注解使用小结
  • 原文地址:https://www.cnblogs.com/fayin/p/14690911.html
Copyright © 2011-2022 走看看