美文网首页
是否应当在axios的响应拦截器里设置弹出toast?

是否应当在axios的响应拦截器里设置弹出toast?

作者: microkof | 来源:发表于2020-09-27 16:32 被阅读0次

    前言

    通常,我们在axios的响应拦截器里写的最多的就是根据HTTP状态码来做出对应的响应,最常见的就是状态码为500的时候,做出不同于200的处理,这个处理有至少3种“流派”:

    1. 在拦截器里只toast,伪代码即toast(res.data.msg),别的什么也不管,后续处理交给业务代码,于是业务代码里须各种if,比如if (res.statusCode === 500) {...}

    2. 在拦截器里只return一个reject,不toast:

    return Promise.reject(res);
    
    1. 前二者的结合体:
    toast(res.data.msg);
    return Promise.reject(res);
    

    到底哪种更科学一点?

    先否掉toast流派

    其实toast流派的思想是,toast的内容由后端编写,因此,在前端开发、测试的过程中就会出现问题:

    1. 后端写msg不一定适合阅读,比如简书自己,当axios出现超时,会在页面顶部弹出axios timeout error(大致是这样,记不太清楚了),你让一群写风花雪月的写手看这个,能看出个寂寞?当发现提示语有问题,需要改,就必须去找后端改,然而我们通常认为,toast显示什么提示属于前端程序员管的事,不应该由后端写死。

    2. 业务流程中并不是凡出错就必须弹出提示,但是toast流派没办法知道哪些提示需要提示,哪些只给前端程序员看看就好。

    然后说说toast流派的优点:比较无脑。但是这其实不是优点。

    所以toast并不是可行方案。

    由于toast方案并不是可行方案,因此也导致“结合体”方案同样不是好的方案。

    reject方案好不好?

    reject方案的实质是将返回res对象改成了返回失败的Promise对象,它的思想是任何操作都有可能有成功和失败2种状态,我们先看看如果不用reject方案,业务代码一般会怎么写:

    this.$axios.get('...A接口...').then((res) => {
      if (res.status === 200) {
        // 只有 200 状态码会进入这个流程
        // ...
        return this.$axios.get('...B接口...')
      } else if (res.status === 500) {
        // 只有 500 状态码会进入这个流程
        // ...
        toast(res.data.msg)
      }
    }).then((val) => {
      if (res.status === 200) {
        // 只有 200 状态码会进入这个流程
        // ...
        return this.$axios.get('...C接口...')
      } else if (res.status === 500) {
        // 只有 500 状态码会进入这个流程
        // ...
        toast(res.data.msg)
      }
    })
    

    然后看看如果用reject方案,会怎么写:

    this.$axios.get('...A接口...').then((res) => {
      // 只有 200 状态码会进入这个流程
      // ...
      return this.$axios.get('...B接口...')
    }, (err) => {
      // 只有 500 状态码会进入这个流程
      // ...
      toast(res.data.msg)
    }).then((res) => {
      // 只有 200 状态码会进入这个流程
      // ...
      return this.$axios.get('...C接口...')
    }, (err) => {
      // 只有 500 状态码会进入这个流程
      // ...
      toast(res.data.msg)
    })
    

    可见:reject方案代码更清晰,代码更少。

    如果有2种以上的状态,怎么区分resolve分支和reject分支?

    比如某接口,返回结果可能有4种状态:

    1. 完全成功
    2. 部分成功,另外部分未知
    3. 部分成功,另外部分失败
    4. 全失败

    这时候怎么区分这4种状态?

    1. 应当根据上下文,首先区分出成功状态和失败状态。比如前三种认为是成功,后2种认为是失败。怎么区分就看团队内怎么商议了。

    2. 根据响应体的status字段区分3种成功,比如status: "abc"、status: "def"、status: "ghi"。同样的,根据status区分2种失败,比如status: "uvw"、status: "xyz"。注意,不要用数字,因为数字相当于“魔术值”,看不出表达的意思。

    注意,这里用的字段是status,而不是code。响应体就不应该使用code,更不能让响应体code取代真正的HTTP状态码,有人说响应体里的code是用于写200、500、403这种错误码。你可拉倒吧,你被业界一些蠢人带偏了多少年还不自知!

    1. 在then的成功回调里,用if(res.data.code === 2001) {}等3个if来处理不同的成功逻辑,在失败回调里用if(res.data.code === 5001) {}等2个if来处理不同的失败逻辑。

    所以toast应该在哪写?

    应当在业务代码和unhandledrejection事件里写。

    1. toast应该在业务代码里写,如果前端程序员觉得后端给的msg写的不错,就不要写回调,交给unhandledrejection,如果后端写的msg读起来很渣,就重写,然后toast即可。

    2. unhandledrejection负责兜底。

    相关文章

      网友评论

          本文标题:是否应当在axios的响应拦截器里设置弹出toast?

          本文链接:https://www.haomeiwen.com/subject/yecluktx.html