Maison  >  Article  >  interface Web  >  Comment gérer le problème de délai d'expiration de la demande Vue Axios

Comment gérer le problème de délai d'expiration de la demande Vue Axios

不言
不言original
2018-06-29 14:45:061519parcourir

Cet article présente principalement la solution parfaite pour le délai d'attente de la demande de vue axios et la configuration d'une nouvelle demande. Il présente également l'utilisation de base d'axios. Les amis dans le besoin peuvent s'y référer

Depuis que vous utilisez Vue2, utilisez. le plug-in axios officiellement recommandé pour appeler l'API Pendant l'utilisation, si le serveur ou le réseau est instable et que des paquets sont abandonnés, comment devez-vous y faire face ?

Raison spécifique

Récemment, l'entreprise travaille sur un projet L'interface de données côté serveur utilise la sortie API de Php, qui. est parfois appelé Le processus échouera et les en-têtes provisoires sont affichés dans Google Chrome.

D'après les solutions proposées par le moteur de recherche, mon problème ne peut pas être résolu

Récemment, j'étudie le concept de programmation de développement AOP, qui est. dans les instructions de développement axios Les axios.Interceptors mentionnés devraient être ce mécanisme, qui réduit le couplage de code, améliore la réutilisabilité du programme et améliore l'efficacité du développement.

Solution 1 avec des pièges

Mon expérience est limitée et je pense que la seule chose que je peux faire est de faire une nouvelle demande après les axios la demande expire. En étudiant le mode d'emploi d'axios, définissez un timeout = 6000 pour celui-ci

axios.defaults.timeout = 6000;

puis ajoutez un coupe-colonne.

// Add a request interceptor
axios.interceptors.request.use(function (config) {
 // Do something before request is sent
 return config;
 }, function (error) {
 // Do something with request error
 return Promise.reject(error);
});
// Add a response interceptor
axios.interceptors.response.use(function (response) {
 // Do something with response data
 return response;
 }, function (error) {
 // Do something with response error
 return Promise.reject(error);
});

La fonction de cet intercepteur est que si la demande expire, l'intercepteur peut capturer les informations puis passer à l'étape suivante, c'est-à-dire que je veux re- demande.

Voici les demandes de données de page pertinentes.

this.$axios.get(url, {params:{load:'noload'}}).then(function (response) {
	//dosomething();
}).catch(error => {
	//超时之后在这里捕抓错误信息.
	if (error.response) {
		console.log('error.response')
		console.log(error.response);
	} else if (error.request) {
		console.log(error.request)
		console.log('error.request')
		if(error.request.readyState == 4 && error.request.status == 0){
			//我在这里重新请求
		}
	} else {
		console.log('Error', error.message);
	}
	console.log(error.config);
});

Après le délai d'attente, une erreur Uncaught (in promise) : timeout of xxx ms dépassé est signalée.

Dans catch, il renvoie une erreur error.request, donc la fonction de nouvelle tentative est effectuée ici Après le test, la fonction de re-demande peut être réalisée bien qu'elle puisse le faire. la fonction de nouvelle demande après expiration du délai est implémentée, mais elle est très gênante. Elle nécessite de définir la nouvelle demande dans chaque page demandant l'API.

Regardez ci-dessus, mon projet contient des dizaines de fichiers .vue si chaque page doit définir le délai d'attente et la fonction de nouvelle demande, alors je deviendrai fou

.

Et il y a un bug sérieux dans ce mécanisme, c'est-à-dire que lorsque le lien demandé échoue ou n'est pas accessible normalement pour d'autres raisons, ce mécanisme échoue, il n'attendra pas les 6 secondes que j'ai définies et il continuera. Lors du brossage, des dizaines de requêtes par seconde peuvent facilement faire tomber le serveur. Veuillez voir l'image ci-dessous. En un clin d'œil, il demande 146 fois.

Solution 2 avec pièges

Étudiez le code source d'axios. le message d'erreur est intercepté dans l'intercepteur axios.interceptors.response, et error.code = "ECONNABORTED", le lien spécifique

https://github.com/axios/axios/blob/26b06391f831ef98606ec0ed406d2be1742e9850/lib/ adapters /xhr.js#L95-L101

// Handle timeout
 request.ontimeout = function handleTimeout() {
  reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED',
  request));
  // Clean up request
  request = null;
 };

Donc, ma solution pour la récupération globale du délai d'attente est comme ceci.

axios.interceptors.response.use(function(response){
....
}, function(error){
	var originalRequest = error.config;
	if(error.code == 'ECONNABORTED' && error.message.indexOf('timeout')!=-1 && !originalRequest._retry){
			originalRequest._retry = true
			return axios.request(originalRequest);
	}
});

Cette méthode peut également implémenter de nouvelles requêtes, mais il y a deux problèmes 1. Elle ne redemande qu'une seule fois si elle expire à nouveau. il s'arrête et ne demandera plus. Le deuxième problème est que je fais de nombreuses opérations sur chaque page avec des requêtes de données, comme des opérations après this.$axios.get(url).then.

Solution parfaite

En programmation AOP, ce dont j'ai besoin est une fonction globale pour la nouvelle demande de délai d'attente, à faire dans axios.Interceptors Après avoir travaillé dur, j'ai cherché des solutions auprès d'autres personnes pour le problème axios sur github, et j'ai finalement trouvé une solution parfaite, qui est celle ci-dessous.

https://github.com/axios/axios/issues/164#issuecomment-327837467

//在main.js设置全局的请求次数,请求的间隙
axios.defaults.retry = 4;
axios.defaults.retryDelay = 1000;
axios.interceptors.response.use(undefined, function axiosRetryInterceptor(err) {
 var config = err.config;
 // If config does not exist or the retry option is not set, reject
 if(!config || !config.retry) return Promise.reject(err);
 // Set the variable for keeping track of the retry count
 config.__retryCount = config.__retryCount || 0;
 // Check if we've maxed out the total number of retries
 if(config.__retryCount >= config.retry) {
  // Reject with the error
  return Promise.reject(err);
 }
 // Increase the retry count
 config.__retryCount += 1;
 // Create new promise to handle exponential backoff
 var backoff = new Promise(function(resolve) {
  setTimeout(function() {
   resolve();
  }, config.retryDelay || 1);
 });
 // Return the promise in which recalls axios to retry the request
 return backoff.then(function() {
  return axios(config);
 });
});

Les autres Les Les méthodes get et post de this.$axios dans les dix pages .vue n'ont pas du tout besoin de modifier leurs codes.

Merci Jooger d'avoir fourni beaucoup de soutien technique pendant ce processus. Ce sont ses informations personnelles https://github.com/jo0ger, merci.

Ce qui suit est une expérience que j'ai faite. . Définissez axios.defaults.retryDelay = 500, demandez www.facebook.com

Si vous avez de meilleures suggestions, dites-le-moi, merci.

Supplément :

Utilisation de base d'axios

vue更新到2.0之后,作者就宣告不再对vue-resource更新,而是推荐的axios,前一段时间用了一下,现在说一下它的基本用法。

首先就是引入axios,如果你使用es6,只需要安装axios模块之后

import axios from 'axios';
//安装方法
npm install axios
//或
bower install axios

当然也可以用script引入

64ef857bf01c92051864c8a6698b61742cacc6d41bbb37262a98f745aa00fbf0

axios提供了一下几种请求方式

axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])

这里的config是对一些基本信息的配置,比如请求头,baseURL,当然这里提供了一些比较方便配置项

//config
import Qs from 'qs'
{
 //请求的接口,在请求的时候,如axios.get(url,config);这里的url会覆盖掉config中的url
 url: '/user',
 // 请求方法同上
 method: 'get', // default
 // 基础url前缀
 baseURL: 'https://some-domain.com/api/',
  
    
 transformRequest: [function (data) {
  // 这里可以在发送请求之前对请求数据做处理,比如form-data格式化等,这里可以使用开头引入的Qs(这个模块在安装axios的时候就已经安装了,不需要另外安装)
  data = Qs.stringify({});
  return data;
 }],
 transformResponse: [function (data) {
  // 这里提前处理返回的数据
  return data;
 }],
 // 请求头信息
 headers: {'X-Requested-With': 'XMLHttpRequest'},
 //parameter参数
 params: {
  ID: 12345
 },
 //post参数,使用axios.post(url,{},config);如果没有额外的也必须要用一个空对象,否则会报错
 data: {
  firstName: 'Fred'
 },
 //设置超时时间
 timeout: 1000,
 //返回数据类型
 responseType: 'json', // default
}

有了配置文件,我们就可以减少很多额外的处理代码也更优美,直接使用

axios.post(url,{},config)
  .then(function(res){
    console.log(res);
  })
  .catch(function(err){
    console.log(err);
  })
//axios请求返回的也是一个promise,跟踪错误只需要在最后加一个catch就可以了。
//下面是关于同时发起多个请求时的处理
axios.all([get1(), get2()])
 .then(axios.spread(function (res1, res2) {
  // 只有两个请求都完成才会成功,否则会被catch捕获
 }));

最后还是说一下配置项,上面讲的是额外配置,如果你不想另外写也可以直接配置全局

axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
//当然还可以这么配置
var instance = axios.create({
 baseURL: 'https://api.example.com'
});

本文只是介绍基本的用法,详细看官方文档https://github.com/axios

我写的两个例子:

使用vue2.0+mintUI+axios+vue-router: https://github.com/Stevenzwzhai/vue-mobile-application

使用vue2.0+elementUI+axios+vue-router: https://github.com/Stevenzwzhai/vue2.0-elementUI-axios-vueRouter, 之前由于没做后端接口,所以运行没数据,现在加了mockjs来返回一些数据,以便于参考。

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

关于vux uploader 图片上传组件的安装使用方法

关于vue.js简单配置axios的方法介绍

VUE中v-bind的用法介绍

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn