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

当使用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实现文件上传和下载功能

    实现文件上传和下载功能是Web应用开发中经常需要涉及的功能之一,Vue作为一款流行的前端框架也能够提供方便灵活的实现方式。下面是详细的攻略过程。 实现文件上传 1. 创建上传组件 首先,我们需要创建一个上传组件。这个组件需要包含一个可以选择文件的按钮和实际上传文件的功能。我们可以使用axios库来发送HTTP请求,从而上传文件。 <template&g…

    Vue 2023年5月28日
    00
  • Vue开发实践指南之应用入口

    让我来详细讲解一下“Vue开发实践指南之应用入口”的完整攻略。 什么是应用入口 应用入口是一个前端项目(如Vue项目)的入口文件,也是一个前端项目的重要组成部分。在Vue项目中,应用入口是指main.js文件。 在Vue项目中,应用入口主要负责以下几个任务: 加载Vue框架和相关插件。 初始化Vue实例。 配置全局组件和Vue指令。 配置全局过滤器。 配置全…

    Vue 2023年5月28日
    00
  • Vue 中v-model的完整用法及原理

    首先我们先来了解一下v-model的基本用法和原理。 v-model的基本用法 在Vue中,v-model被用来实现表单元素和Vue实例之间的双向数据绑定。v-model通常和表单元素input、textarea、select等配合使用。将 v-model 赋值给一个普通的变量,这个变量就可以被修改以响应用户的输入和交互。 v-model的基本语法如下: &…

    Vue 2023年5月27日
    00
  • 详解使用Vue Router导航钩子与Vuex来实现后退状态保存

    本文将详细讲解如何使用Vue Router导航钩子与Vuex来实现后退状态保存的解决方案。 什么是导航钩子? 导航钩子是Vue Router提供的一种功能,用于在路由导航过程中拦截操作,触发特定的函数。导航钩子包含全局导航钩子和路由级别导航钩子。 对于全局导航钩子,可以用于全局拦截路由导航,比如用户未登录时跳转到登录页面。而对于路由级别导航钩子,可以用于针对…

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

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

    Vue 2023年5月28日
    00
  • Vue v-model实现案例介绍

    让我们来详细讲解“Vue v-model实现案例介绍”的完整攻略。 什么是Vue v-model? Vue是一个流行的JavaScript框架,v-model是Vue的一个指令,用于在表单控件和Vue实例之间建立双向数据绑定。 通过使用v-model指令,当用户在表单控件中输入内容时,Vue实例中的相应数据将自动更新。同时,当在Vue实例中更新数据时,表单控…

    Vue 2023年5月27日
    00
  • vue日历/日程提醒/html5本地缓存功能

    Vue日历/日程提醒攻略 简介 在Vue中实现日历/日程提醒功能,可以帮助用户更好地规划时间并且提醒用户该做什么。这里介绍一种通过使用Vue.js及相关的插件来实现 Vue日历/日程提醒的方法 开发环境 Vue.js(2.0+) vue-calendar-component(一个简单好用的Vue日历组件) vue-notification(Vue提醒/通知组…

    Vue 2023年5月29日
    00
  • JS实现的点击表头排序功能示例

    下面是详细的攻略: 什么是点击表头排序功能? 点击表头排序是一种JavaScript编写的功能,在表格中点击表头时,可以按照表头所指向的列数据的大小为依据,对表格的行进行排序的功能。 代码实现 以下是一份实现点击表头排序功能的代码示例,其中使用jQuery库和ES6箭头函数: // 获取表格 var table = $(‘table.sortable’); …

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