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

2020-09-27  本文已影响0人  microkof

前言

通常,我们在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负责兜底。

上一篇 下一篇

猜你喜欢

热点阅读