sincronas promesas pagina orden funciones funcion ejecutar ejecucion controlar cargar autoejecutables asincronia asincrona antes javascript function google-chrome runtime trace

promesas - orden de ejecucion de funciones javascript



Cómo obtener llamadas de función de Javascript/Rastreo en tiempo de ejecución (6)

Dale una oportunidad a diyism_trace_for_javascript.htm:

https://code.google.com/p/diyism-trace/downloads/list

eval(''window.c=function(){3+5;}''); declare_ticks_for(window); function a(k, c) { return k + 2; } function b() { 4 + 3; a(3, {''a'':''c'',''b'':''d''}); c(); return 5 + 4; } b();

Ver registros en la pestaña de la consola de Chrome o Firefox

Mientras interactúo con mi aplicación basada en AJAX en RUNTIME, me gustaría que la consola emita todas las funciones a las que está llamando. (así que no hay rastro de pila, ni puntos de interrupción, ni perfiles ni nada)

Entonces, por ejemplo, digamos que presioné un botón en la página. Me gustaría que devuelva todas las funciones por las que pasó cuando sucedió:

Entonces vería en la consola algo como (cuando presioné un botón):

1. button1Clicked(); 2. calculating(); 3. printingResults();

Lo que básicamente significa que button1Clicked () llamó a calculating () que llamó printingResults ()

¿Hay alguna utilidad, o complemento, navegador, o quizás alguna forma en el idioma para hacer esto? Estoy usando google chrome, por cierto.

ps y NO No quiero pasar por cada función y agregar un "console.log("inside function X")" b / c que es demasiado trabajo

pps como un bono adicional me gustaría ver los argumentos pasados ​​en las funciones también, pero tal vez eso lo está empujando. :>


Esto se llama perfilado y Chrome y Firebug lo tienen incorporado. En las Herramientas para desarrolladores de Chrome , vaya a la pestaña de perfiles y haga clic en el botón de grabación (círculo). Realice su ajax y después de su respuesta, haga clic nuevamente en el botón de grabación para detener. Los resultados del perfil aparecerán en el panel derecho.

Tenga en cuenta que esto le proporcionará todo, por lo que si está utilizando una biblioteca como jQuery, la gran mayoría de las llamadas a funciones serán basura para usted. He intentado esto varias veces y me parece mucho más útil hacer el trabajo de console.log(''inside <method>'') .


He utilizado la solución de @ Briguy37 con una mejora. En mi caso, no quería rastrear las funciones de algunas bibliotecas, así que agregué algo de código para excluirlas. Aquí es cómo se utiliza:

  • Primero, incluya la definición de las funciones que no desea rastrear;
  • excludeLoggingToNamespace para enumerar las funciones definidas hasta ahora y excluirlas;
  • Incluya la definición de las funciones que desea rastrear;
  • Llame a addLoggingToNamespace para agregar la capacidad de registro a las funciones definidas en el paso anterior.

Ejemplo:

<script src="js/someLibrary.js"></script> <script> functionLogger.excludeLoggingToNamespace(window); </script> <script src="js/codeIWantToTraceHere.js"></script> <script> functionLogger.addLoggingToNamespace(window); </script>

Aquí está el código que agregué a la solución de @Guyuy37:

var excludedFunctions = {}; functionLogger.excludeLoggingToNamespace = function(namespaceObject){ for(var name in namespaceObject){ var potentialFunction = namespaceObject[name]; if(Object.prototype.toString.call(potentialFunction) === ''[object Function]'') { excludedFunctions[name] = name; } } };

Y tuve que modificar el método addLoggingToNamespace de @ Briguy37 para tener en cuenta el hash de funciones excluidas:

functionLogger.addLoggingToNamespace = function(namespaceObject){ for(var name in namespaceObject){ var potentialFunction = namespaceObject[name]; if(Object.prototype.toString.call(potentialFunction) === ''[object Function]'' && !excludedFunctions[name]) { namespaceObject[name] = functionLogger.getLoggableFunction(potentialFunction, name); } } };


No puedo pensar en una buena manera de interceptar todas las llamadas de funciones globalmente para insertar el registro (aunque hay una solución decente en la sección de actualización a continuación).

En su lugar, ¿qué tal si solo agrega el registro a las funciones en un determinado espacio de nombres que le interesa? Puedes hacer esto con el siguiente código de configuración:

var functionLogger = {}; functionLogger.log = true;//Set this to false to disable logging /** * Gets a function that when called will log information about itself if logging is turned on. * * @param func The function to add logging to. * @param name The name of the function. * * @return A function that will perform logging and then call the function. */ functionLogger.getLoggableFunction = function(func, name) { return function() { if (functionLogger.log) { var logText = name + ''(''; for (var i = 0; i < arguments.length; i++) { if (i > 0) { logText += '', ''; } logText += arguments[i]; } logText += '');''; console.log(logText); } return func.apply(this, arguments); } }; /** * After this is called, all direct children of the provided namespace object that are * functions will log their name as well as the values of the parameters passed in. * * @param namespaceObject The object whose child functions you''d like to add logging to. */ functionLogger.addLoggingToNamespace = function(namespaceObject){ for(var name in namespaceObject){ var potentialFunction = namespaceObject[name]; if(Object.prototype.toString.call(potentialFunction) === ''[object Function]''){ namespaceObject[name] = functionLogger.getLoggableFunction(potentialFunction, name); } } };

Luego, para cualquier objeto de espacio de nombres al que desee agregar el registro, simplemente llame:

functionLogger.addLoggingToNamespace(yourNamespaceObject);

Aquí hay un violín para verlo en acción.

ACTUALIZAR
Tenga en cuenta que puede llamar a functionLogger.addLoggingToNamespace(window); para agregar el registro a todas las funciones globales en el momento de la llamada. Además, si realmente lo desea, puede atravesar el árbol para encontrar cualquier función y actualizarla en consecuencia. La única desventaja de este método es que solo funciona en las funciones que existen en ese momento. Por lo tanto, aún no es la mejor solución, pero es mucho menos trabajo que agregar las declaraciones de registro a mano :)



Una variación de la solución de Briguy37, escribí una que acepta una función para llamar antes de cada método. También funciona con las clases de ECMAScript 6, donde los métodos no se enumeran por ... en. Lo estoy usando para modificar prototipos de objetos, para agregar el registro a todas las nuevas instancias de mi objeto.

function inject(obj, beforeFn) { for (let propName of Object.getOwnPropertyNames(obj)) { let prop = obj[propName]; if (Object.prototype.toString.call(prop) === ''[object Function]'') { obj[propName] = (function(fnName) { return function() { beforeFn.call(this, fnName, arguments); return prop.apply(this, arguments); } })(propName); } } } function logFnCall(name, args) { let s = name + ''(''; for (let i = 0; i < args.length; i++) { if (i > 0) s += '', ''; s += String(args[i]); } s += '')''; console.log(s); } inject(Foo.prototype, logFnCall);