在vue中axios设置timeout超时的操作

yizhihongxing

当使用axios在Vue中进行数据请求时,可能会遇到服务器响应非常缓慢或者出现网络问题等情况,由此导致前端请求一直在等待响应,造成用户体验不佳。为了解决这类问题,我们可以通过设置axios的timeout超时时间来规定前端在等待响应的最大时间,如果超过这个时间则取消请求,并且返回一个错误提示。

下面是设置axios timeout的完整攻略和两条示例说明:

设置全局 timeout

我们可以通过axios的默认配置来全局设置timeout,这样所有的axios请求都会拥有相同的超时时间,可以在Vue项目中的main.js中进行如下设置:

import axios from 'axios'

axios.defaults.timeout = 10000 // 设置默认的超时时间,单位是毫秒

Vue.prototype.$http = axios

在上述代码中,我们将axios请求的默认超时时间设置为10秒。如果我们在实际请求中不需要设置其他超时时间,就可以直接使用该全局配置。

设置单个请求的 timeout

有时候我们可能需要针对某个特定的请求来设置超时时间。在这种情况下,我们可以在请求的config中增加一个timeout属性来设置超时时间,如下所示:

axios.get('/api/user', { 
  params: { 
    id: 12345 
  },
  timeout: 5000 // 设置该请求的超时时间为5秒
}).then(response => {
  console.log(response.data)
}).catch(error => {
  console.log(error.message)
})

上述代码中,我们在get请求的config中增加了timeout属性,并将超时时间设置为5秒。

示例1:完整代码

<template>
  <div>
    {{ message }}
  </div>
</template>

<script>
import axios from 'axios'

export default {
  name: 'Example',
  data() {
    return {
      message: ''
    }
  },
  created() {
    axios.get('/api/user', {
      params: {
        id: 12345
      },
      timeout: 5000
    }).then(response => {
      this.message = response.data
    }).catch(error => {
      console.log(error.message)
    })
  }
}
</script>

上述代码中,我们在Vue组件的created生命周期中发送了一个get请求,并设置了超时时间为5秒。请求成功后,将响应结果赋值给组件中的message。

示例2:防止超时重复发送

在实际使用中,可能会遇到在请求超时之后,希望重新发送请求的情况。这时候我们可以在axios的interceptors拦截器中进行处理。

axios.interceptors.response.use(
  response => {
    return response
  },
  error => {
    if (axios.isCancel(error)) {
      console.log('Request canceled:', error.message)
    } else if (error.code === 'ECONNABORTED') {
      console.log('Request timeout!')
      handleTimeout(error.config) // 处理超时事件
    } else {
      console.log('Request error:', error.message)
      return Promise.reject(error)
    }
  }
)

let pendingRequests = new Map() // 存储正在进行的请求
let CancelToken = axios.CancelToken

function handleTimeout(config) {
  let key = getRequestKey(config)
  let request = pendingRequests.get(key)
  if (request) {
    request.cancel('Timeout!') // 取消该请求
    pendingRequests.delete(key)
    sendRequest(config) // 重新发送请求
  }
}

function getRequestKey(config) {
  return [config.method, config.url, JSON.stringify(config.params)].join('&')
}

function sendRequest(config) {
  let key = getRequestKey(config)
  let request = axios.request(config)
  request.then(response => {
    pendingRequests.delete(key)
    return response
  }).catch(error => {
    pendingRequests.delete(key)
    return Promise.reject(error)
  })
  pendingRequests.set(key, request)
}

export default {
  get(url, params, timeout = 5000) {
    let config = {
      method: 'get',
      url: url,
      params: params,
      timeout: timeout,
      cancelToken: new CancelToken(function executor(cancel) {
        let key = getRequestKey(config)
        if (pendingRequests.has(key)) {
          cancel('Request canceled')
        } else {
          pendingRequests.set(key, {cancel})
        }
      })
    }
    return sendRequest(config)
  },
  post(url, data, timeout = 5000) {
    let config = {
      method: 'post',
      url: url,
      data: data,
      timeout: timeout,
      cancelToken: new CancelToken(function executor(cancel) {
        let key = getRequestKey(config)
        if (pendingRequests.has(key)) {
          cancel('Request canceled')
        } else {
          pendingRequests.set(key, {cancel})
        }
      })
    }
    return sendRequest(config)
  }
}

上述代码中我们使用了一个pendingRequests的Map来存储正在进行的请求,每个请求的key是由请求的method、url和params组成的。当第一次发送一个请求时,我们将它加入pendingRequests中,同时创建一个cancelToken,并在cancelToken中设置一个executor,在executor中判断该请求是否已经在pendingRequests中存在。如果已经存在则调用其cancel方法取消请求。如果不存在就将一个{cancel}对象加入pendingRequests中。

当请求超时后,我们可以在拦截器的错误处理函数中通过判断error.code是否为‘ECONNABORTED’来判断该请求是否超时。如果请求超时,我们可以通过getRequestKey函数获取该请求的key,并在pendingRequests中获取该请求对象。然后我们会取消该请求,并调用sendRequest函数重新发送同样的请求,并更新pendingRequests。

最后,我们在axios使用过程中不再调用axios的方法,而是调用我们自身的get和post方法,这两个方法内部包含了超时重发的逻辑。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:在vue中axios设置timeout超时的操作 - Python技术站

(0)
上一篇 2023年5月29日
下一篇 2023年5月29日

相关文章

  • 浅谈vue项目重构技术要点和总结

    浅谈Vue项目重构技术要点和总结 在Vue项目重构的过程中,需要注意以下几个技术要点: 1. 把公共功能封装成组件 在项目重构的过程中,需要尽量避免重复的代码。因此,我们可以把一些公共的功能封装成组件,供其他地方复用。例如,我们可以封装一个翻页组件,用于多处分页展示。如下所示: <template> <div> <button …

    Vue 2023年5月28日
    00
  • 使用SpringBoot+EasyExcel+Vue实现excel表格的导入和导出详解

    使用SpringBoot+EasyExcel+Vue实现excel表格的导入和导出,主要步骤如下: 1.引入EasyExcel依赖 在pom.xml中引入EasyExcel依赖: <!– 引入EasyExcel –> <dependency> <groupId>com.alibaba</groupId> &…

    Vue 2023年5月28日
    00
  • 在vue中给后台接口传的值为数组的格式代码

    在Vue中向后台接口传递值需要通过HTTP请求发送数据,一般的格式都是以JSON格式发送。如果要发送一个数组到后台,则需要将该数组转换为JSON格式,再通过HTTP请求发送数据。下面是用数组给后台传值的详细攻略,包含两个示例说明。 将数组转换成JSON 在Vue中需要将数组转换为JSON字符串格式,以便HTTP请求进行发送。使用JSON.stringify(…

    Vue 2023年5月28日
    00
  • 浅谈Vue2.0中v-for迭代语法的变化(key、index)

    浅谈Vue2.0中v-for迭代语法的变化(key、index) 传统的v-for迭代语法 Vue 1.x和2.x在v-for指令上有一些差异,Vue 1.x中v-for迭代语法支持以下形式: <div v-for="item in items"> {{ item }} </div> 在Vue 1.x中,v-for…

    Vue 2023年5月28日
    00
  • Vue的data为啥只能是函数原理详解

    Vue的data中为什么只能是函数呢?这是一个常见的Vue面试题,其主要原因是为了保证每个Vue组件实例都有一个独立的数据对象,在多个组件实例中互不干扰。 具体来说,当一个组件实例化时,如果data选项是一个对象,那么这个对象会被所有这个组件的实例共享,这样就会导致一个实例修改了data中的值,其他实例中的值也会发生改变,这样就无法实现组件复用了。 而当我们…

    Vue 2023年5月28日
    00
  • vue自定义表单生成器form-create使用详解

    Vue自定义表单生成器form-create使用详解 1. 什么是form-create? form-create是一个基于Vue.js的自定义表单生成器。它可以根据预设的模板或者自定义的UI组件来动态生成表单,方便开发者快速构建各种表单,能够提高开发效率。 2. 如何使用form-create? 2.1 安装 首先,我们需要安装form-create,可以…

    Vue 2023年5月28日
    00
  • 10分钟快速上手VueRouter4.x教程

    10分钟快速上手VueRouter4.x教程: VueRouter是Vue.js官方的路由管理器,用于处理单页应用程序的导航,它可以帮助我们在Web应用程序中导航和管理视图,并且也可以控制浏览器的前进和后退。VueRouter可以非常快速地搭建起一个SPA应用,通过本教程,您可以在10分钟内了解如何在Vue 4.x项目中使用VueRouter。 安装vue-…

    Vue 2023年5月27日
    00
  • Vue项目中ESLint配置超全指南(VScode)

    下面我将详细解释如何在Vue项目中配置ESLint,并使用VS Code进行代码提示和自动修复。 步骤一:安装ESLint 首先,我们需要在Vue项目中安装ESLint和相关依赖包: npm install eslint eslint-plugin-vue –save-dev 其中,eslint-plugin-vue用于支持Vue文件的ESLint检查。 …

    Vue 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部