以下这段请求代码有3个小问题?

instance.interceptors.request.use(config => {

// 添加全局的loading...

if (!Object.keys(this.queue).length) {

// Spin.show() // 不建议开启,因为界面不友好

}

this.queue[url] = true

return config

}, error => {

return Promise.reject(error)

})

// 响应拦截

instance.interceptors.response.use(res => {

this.destroy(url)

const { data, status } = res

return { data, status }

}, error => {

this.destroy(url)

let errorInfo = error.response

if (!errorInfo) {

const { request: { statusText, status }, config } = JSON.parse(JSON.stringify(error))

errorInfo = {

statusText,

status,

request: { responseURL: config.url }

}

}

addErrorLog(errorInfo)

return Promise.reject(error)

})

destory函数:

destroy (url) {

delete this.queue[url]

if (!Object.keys(this.queue).length) {

// Spin.hide()

}

}
  1. queue是干什么用的 只是添加了又删除 维护这个队列我不知道是为什么
  2. 为什么要return Promise.reject(error)而不是return error?
  3. 为什么用Object.keys(this.queue).length来判断长度 和直接用queue.length又什么区别?
阅读 2.2k
2 个回答
  1. this.queue 的实际作用是:标记当前是否有未完成的请求,如果还有,就显示加载动画(也就是执行Spin.show());
  2. 也许是开发者比较懒,把最后一个操作顺便当成返回值了;
  3. 如果 url 不是数字的话,queue[url] = true 并不会影响 queue.length的值,所以不能通过 length 来判断有没有内容,只能用 Object.keys 枚举所有键值来判断。

当然,代码里的这个实现不是很优雅。因为它使用 url 作为键名,如果有两个同 url 的请求的话,后一个会把前一个覆盖掉,导致加载提示提前关闭;返回的 Promise 也有可能造成内存无法回收。
this.queue 的实现应当采用数组,更简单的方法是直接对请求数量进行计数,计数为 0 的时候关闭加载提示。

先回答第三个问题吧

3.为什么用Object.keys(this.queue).length来判断长度 和直接用queue.length又什么区别?

destory函数里有delete操作。如果this.queue是个数组,会导致this.queue变成稀疏数组。所以Object.keys(this.queue).lengththis.queue.length是有区别的:

var a = [1,2,3];
delete a[1];
console.log(a.length) // 3
console.log(Object.keys(a).length) // 2
推荐问题
宣传栏