详解如何消除axios拦截中的if

目录
  • 基本拦截
  • 设计轮子
    • 思考方向
    • 轮子骨架
    • 详细实现
  • 实践
  • 总结

基本拦截

axios的响应错误拦截中,难免会对error.status做各种各样的if判断,又或者switch。为了防止枯燥乏味的生活(给自己挖坑,换一种姿势去写拦截

// 以下大概是日常碰到的操作,拦截响应,判断status做相应操作
function login () {
  console.log('登陆逻辑')
  return promise.reject(error)
}
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
  // 对响应数据做点什么
  return response;
}, function (error) {
  if (error.status === 401) {
    // 401重新登录
    console.log('未登陆')
    return login(error)
  } else if (error.status === 404) {
    console.log('404-什么都没')
    return promise.reject(error)
  } else if (error.status === 422) {
    console.log(error.response.data.message)
    return promise.reject(error)
  } else if (error.status === 500) {
    console.log('服务器内部错误')
    return promise.reject(error)
  } else {
    // 其他请求,直接抛出让业务去处理
    return promise.reject(error)
  }
});

设计轮子

思考方向

首先思考下怎么实现这个东西

  • 需要一个在内部消化if的逻辑判断
  • 根据判断去执行相应的逻辑,意味着我们要在内部维护一个逻辑数组(以下称为管道数组),配合成功后即触发对应管道。所以在开始调用函数去执行前,先要收集好管道。这个方法需要传一个标记(用来判断是否匹配)和回调函数(匹配成功后的逻辑)
  • 除了传标记,需要传一个payload(例如拦截中的error)参数,payload可以让我们在回调函数做出更多的对应操作
  • 在最后再添加一个default函数来收集匹配失败后的函数。

现在,已经在心中拟好了一个小轮子的五脏六腑。

轮子骨架

// 定义个一个class
class Enterclose {
  constructor () {
    // 维护管道数组
    this.pond = {}
    // 默认管道
    this._default = null
  }
  /**
   * 收集管道
   * callback(payload)
   * @param {any} sign 标记
   * @param {Function|Object} callback 回调函数|函数this
   * @return this
   * */
  use (sign, callback) {
    return this
  }
  /**
   * 收集匹配失败的管道
   * callback(payload)
   * @param {Function} callback 回调函数|函数this
   * @return this
   * */
  default (callback) {
    this._default = callback
    return this
  }
  /**
   * 执行管道流
   * @param {any} sign 标记
   * @param {any} payload
   * @return
   */
  start (sign, payload) {
  }
}

详细实现

以上把基本的api骨架写好,然后再一个一个慢慢实现内部的逻辑。

首先是use,用来收集管道,需求中标记是唯一的,所以我们的this.ponds的结构是{标记: callback}

use (sign, callback) {
    this.ponds[sign] = callback
    return this
}

其中我们需要一个方法用来启动Enterclose

通过getCallback函数去筛选和标记匹配的管道,返回对应的函数。这样一个消除if的小轮子就搞好啦

start (sign, payload) {
    const fn = this.getCallback(sign)
    if (fn) {
      return fn(payload)
    }
}
/**
* 根据标记获取函数
* @param {*} sign
* @return {Function}
*/
getCallback (sign) {
    const key = Object.keys(this.ponds).find(key => key === sign)
    if (key) {
      return this.ponds[key]
    } else if (this._default) {
      return this._default
    }
}

实践

创建实例,用use和default收集管道,然后在拦截中通过start触发判断

const enterclose = new Enterclose()
// 收集管道
enterclose
.use(401, function (error) {
  console.log('未登陆')
  return login(error)
})
.use(404, function (error) {
  console.log('404-什么都没')
  return promise.reject(error)
})
.use(429, function (error) {
  console.log(error.response.data.message)
  return promise.reject(error)
})
.use(500, function (error) {
  console.log('服务器内部错误')
  return promise.reject(error)
})
.default(function (error) {
  // 收集默认管道
  return promise.reject(error)
})
axios.interceptors.response.use(function (response) {
  // 对响应数据做点什么
  return response;
}, function (error) {
  // 启动
  return enterclose.start(error.status, error)
});

你也可以根据自己的场景做一些调整,例如支持Promise啊,或者说加一个finally函数,每次走管道最后都会调用这个回调函数之类

总结

到此这篇关于如何消除axios拦截中if的文章就介绍到这了,更多相关消除axios拦截的if内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Vue2.0 axios前后端登陆拦截器(实例讲解)

    vue更新到2.0之后,作者就宣告不再对vue-resource更新,而是推荐使用axios.前段时间第一次在项目里用到vue,关于登陆问题,这里写一下心得. 首先后端: import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import com.lovnx.gateway.po.User; import javax.servlet.http.HttpServletRequest; import jav

  • vue 实现axios拦截、页面跳转和token 验证

    第一步: 路由 多添加一个自定义字段 requireAuth path: '/repository', name: 'repository', meta: { requireAuth: true, // 添加该字段,表示进入这个路由是需要登录的 }, component: Repository 第二步: router.beforeEach((to, from, next) => { if (to.meta.requireAuth) { // 判断该路由是否需要登录权限 if (store.sta

  • axios拦截设置和错误处理方法

    现在vue的官方包已经不更新vue-resource了,转而推荐axios,下面是项目实战是总结的axios插件设置: /** * @file Axios的Vue插件(添加全局请求/响应拦截器) */ // https://github.com/mzabriskie/axios import axios from 'axios' // 拦截request,设置全局请求为ajax请求 axios.interceptors.request.use((config) => { config.heade

  • axios使用拦截器统一处理所有的http请求的方法

    axios使用拦截器 在请求或响应被 then 或 catch 处理前拦截它们. http request拦截器 // 添加请求拦截器 axios.interceptors.request.use(function (config) { // 在发送请求之前做些什么 return config; }, function (error) { // 对请求错误做些什么 return Promise.reject(error); }); http respones拦截器 // 添加响应拦截器 axio

  • 详解如何消除axios拦截中的if

    目录 基本拦截 设计轮子 思考方向 轮子骨架 详细实现 实践 总结 基本拦截 axios的响应错误拦截中,难免会对error.status做各种各样的if判断,又或者switch.为了防止枯燥乏味的生活(给自己挖坑,换一种姿势去写拦截 // 以下大概是日常碰到的操作,拦截响应,判断status做相应操作 function login () { console.log('登陆逻辑') return promise.reject(error) } // 添加响应拦截器 axios.intercept

  • 详解Java分布式缓存系统中必须解决的四大问题

    目录 缓存穿透 缓存击穿 缓存雪崩 缓存一致性 分布式缓存系统是三高架构中不可或缺的部分,极大地提高了整个项目的并发量.响应速度,但它也带来了新的需要解决的问题,分别是: 缓存穿透.缓存击穿.缓存雪崩和缓存一致性问题. 缓存穿透 第一个比较大的问题就是缓存穿透.这个概念比较好理解,和命中率有关.如果命中率很低,那么压力就会集中在数据库持久层. 假如能找到相关数据,我们就可以把它缓存起来.但问题是,本次请求,在缓存和持久层都没有命中,这种情况就叫缓存的穿透. 举个例子,如上图,在一个登录系统中,有

  • 详解Oracle在out参数中访问光标

    详解Oracle在out参数中访问光标 一 概念 申明包结构 包头:负责申明 包体:负责实现 二 需求 查询某个部门中所有员工的所有信息 三 包头 CREATE OR REPLACE PACKAGE MYPACKAGE AS type empcursor isref cursor; procedure queryEmplist(dno in number,emplist out empcursor); END MYPACKAGE; 四 包体 包体需要实现包头中声明的所有方法 CREATE OR

  • 详解MySQL导出指定表中的数据的实例

    详解MySQL导出指定表中的数据 要求: 1. 不导出创表的语句,因为表已经建好:默认会导出,先drop table然后create table: 2. 导出的insert语句加上ignore,允许重复执行:默认不会加上ignore: 3. insert语句中列出表中的字段,看得更清楚:默认不会: 4. 分记录生成多条insert语句,修改起来比较容易:默认是一条: 最终结果如下: mysqldump -pxxxxxx qzt qf1_mail_account --no-create-info

  • 详解K-means算法在Python中的实现

    K-means算法简介 K-means是机器学习中一个比较常用的算法,属于无监督学习算法,其常被用于数据的聚类,只需为它指定簇的数量即可自动将数据聚合到多类中,相同簇中的数据相似度较高,不同簇中数据相似度较低. K-MEANS算法是输入聚类个数k,以及包含 n个数据对象的数据库,输出满足方差最小标准k个聚类的一种算法.k-means 算法接受输入量 k :然后将n个数据对象划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高:而不同聚类中的对象相似度较小. 核心思想 通过迭代寻找

  • 详解如何在Android Studio中添加RecyclerView-v7支持包

    一直知道RecyclerView可以代替ListView.GridView使用,听说功能很强大,但还没有去学习过.今天想学习,没想到还没开始便撞墙了.输入Recycler,只有这两个东西,没有提示RecyclerView,说明支持包中没有. 最后一番百度后,终于解决(真不敢想象没有网络的情况下,怎么开发.怎么解决问题). 1.打开SDK Manager,在Extras树下找到Android Support Library,下载好支持包.RecyclerView在v7-21版本就出来了.我这里不用

  • 详解C++调用Python脚本中的函数的实例代码

    1.环境配置 安装完python后,把python的include和lib拷贝到自己的工程目录下 然后在工程中包括进去 2.例子 先写一个python的测试脚本,如下 这个脚本里面定义了两个函数Hello()和_add().我的脚本的文件名叫mytest.py C++代码: #include "stdafx.h" #include <stdlib.h> #include <iostream> #include "include\Python.h&quo

  • 详解如何获取C#类中发生数据变化的属性信息

    一.前言# 在平时的开发中,当用户修改数据时,一直没有很好的办法来记录具体修改了那些信息,只能暂时采用将类序列化成 json 字符串,然后全塞入到日志中的方式,此时如果我们想要知道用户具体改变了哪几个字段的值的话就很困难了.因此,趁着这个假期,就来解决这个一直遗留的小问题,本篇文章记录了我目前实现的方法,如果你有不同于文中所列出的方案的话,欢迎指出. 代码仓储地址:https://github.com/Lanesra712/ingos-common/tree/master/sample/csha

  • 详解如何在Android studio中更新sdk版本和build-tools版本

    一.首先看下Android开发用到的sdk目录: build-tools 保存着一些Android平台相关通用工具,比如adb.和aapt.aidl.dx等文件.  aapt即Android Asset Packaging Tool , 在SDK的build-tools目录下. 该工具可以查看, 创建, 更新ZIP格式的文档附件(zip, jar, apk). 也可将资源文件编译成二进制文件.  Adb 即android debug bridge 管理模拟器和真机的万能工具,ddms 调试环境 

  • 详解如何为SpringBoot项目中的自定义配置添加IDE支持

    导言 代码是写给人看的,不是写给机器看的,只是顺便计算机可以执行而已 --<计算机程序的构造和解释(SICP)> 导言 在我们的项目里经常会出现需要添加自定义配置的应用场景,例如某个开关变量,在测试环境打开,在生产环境不打开,通常我们都会使用下面的代码来实现,然后在Spring Boot配置文件中添加这个key和Value Application.java: application.properties 或者是没有使用@Value而直接在XML中使用我们配置的属性值 application.x

随机推荐