2017-04-20 5 views
3

J'essaie de trouver comment identifier le nom de la fonction qui a lancé l'appel Ajax par programmation en utilisant JavaScript ou jQuery pour une base de code existante.Comment identifier le nom de la fonction appelant dans un appel AJAX ou XMLHttpRequest?

Je travaille sur l'instrumentation d'une grande base de code existante et essaye donc d'identifier le nom de la fonction qui est en corrélation avec les requêtes AJAX. Donc, il y a déjà beaucoup de code et modifier chaque méthode ne semble pas être la meilleure approche. Donc, j'essaie de penser à une approche générique qui peut fonctionner pour toutes les méthodes. Le code a déjà un wrapper générique autour de l'appel AJAX, donc je peux accrocher dans les points d'entrée et de sortie de la méthode.

Par exemple. dans le code ci-dessous, dans la fonction always, j'ai besoin de connaître le nom de la fonction initiateur ou la pile d'appels.

function ajaxWrapper(){ 
 
var jqxhr = $.ajax("https://jsonplaceholder.typicode.com/posts/1") 
 
    .done(function() { 
 
    console.log("success"); 
 
    }) 
 
    .fail(function() { 
 
    console.log("error"); 
 
    }) 
 
    .always(function() { 
 
    console.log("complete"); 
 
    // TODO: Who Initiated the call ? 
 
    }); 
 
} 
 

 
function initiator1(){ 
 
\t initiator2(); 
 
} 
 

 
function initiator2(){ 
 
\t ajaxWrapper(); 
 
} 
 

 
initiator1();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Qu'ai-je essayé?

  1. Je sais une approche utilise la définition des en-têtes personnalisés dans la méthode beforeSend et toujours rappel reçoit l'objet jqXHR comme paramètre. Mais cela ne semble pas être une approche appropriée car je ne peux pas modifier toutes les fonctions pour envoyer le nom de la méthode en tant que paramètre. L'approche

  2. arguments.callee.caller approche, mais elle ne semble pas fonctionner dans le cas des méthodes asynchrones. En outre, cette fonctionnalité semble être obsolète pour des raisons de performances et de sécurité.

Remarque: Je ne recherche pas ces informations à des fins de débogage. Je connais déjà la pile d'appels Async, les solutions Initiator et console.trace disponibles dans l'outil des développeurs.

Répondre

2

Une option consiste à générer la pile d'appels dans votre encapsuleur, car jusqu'à ce point vous êtes dans une chaîne d'appel de fonction de synchronisation.

var err = new Error(); 
var stack = err.stack; 

Et l'utiliser plus tard dans le rappel, car il est disponible dans le cadre d'une portée plus élevée. (Les portées ne se soucient pas de l'asynchrone.)

Vous aurez besoin de faire un peu d'analyse (spécifique au navigateur) sur cette pile d'appels. Je ne sais pas ce que vous avez l'intention de faire avec l'initiateur, mais vous voudrez peut-être garder toute la chaîne, pas seulement la première.

Notez également que cette technique est unreliable et vous ne devriez pas l'utiliser pour quelque chose de critique.

function ajaxWrapper(){ 
 
var err = new Error(); 
 
var stack = err.stack; 
 
var jqxhr = $.ajax("https://jsonplaceholder.typicode.com/posts/1") 
 
    .done(function() { 
 
    console.log("success"); 
 
    }) 
 
    .fail(function() { 
 
    console.log("error"); 
 
    }) 
 
    .always(function() { 
 
    console.log("complete"); 
 
    // TODO: Who Initiated the call ? 
 
    console.log(stack); 
 
    }); 
 
} 
 

 
function initiator1(){ 
 
\t initiator2(); 
 
} 
 

 
function initiator2(){ 
 
\t ajaxWrapper(); 
 
} 
 

 
initiator1();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

+0

+1 Merci Alin, savez-vous une implication de la performance de la création d'un grand nombre d'objets d'erreur que je dois ajouter ce code à l'emballage ajax générique? Et est-ce une bonne pratique de créer un objet Erreur lorsqu'il n'y a pas d'erreur fonctionnelle ou technique? – Agalo

+0

@Agalo Le surdébit de l'objet Erreur est, selon moi, négligeable par rapport à la surcharge de la requête HTTP à laquelle ils sont attachés. –