使用 AOP 调用方法前后的 Javascript 控制台输出 [英] Javascript console output before and after method call with AOP

查看:29
本文介绍了使用 AOP 调用方法前后的 Javascript 控制台输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想测量方法的计算时间.

I would like to measure the computing time of methods.

一个不错的方法是 (您如何对 JavaScript 代码进行性能测试?) 与 console.time('Function #1');console.timeEnd('Function #1');

A nice way is (How do you performance test JavaScript code?) with console.time('Function #1'); and console.timeEnd('Function #1');

我的想法是在生命周期方法上添加这些控制台输出.在这种情况下,使用 SAPUI5 之类的 createContent:funtion(){}; 方法.

My idea is to add these console outputs on lifecycle-methods. In this case using SAPUI5 like createContent:funtion(){}; methods.

这应该可以通过 AOP 使用 before()after() 来计算时间.

This should be possible with AOP using before() and after() to runt the time counting.

您建议使用哪种 AOP 框架以及如何在需要自动修改标识字符串Function #1"的情况下实现它?

Which AOP framework would you suggest and how to implement it with the need of modifying the identification string "Function #1" automatically?

推荐答案

这应该可以通过 AOP 使用 before() 和 after() 来计算时间.

This should be possible with AOP using before() and after() to runt the time counting.

正如已经提到的,人们真的不需要真正的面向方面的编程为了在 JavaScript 中解决此类任务.但是这种语言可能值得一些更标准化的method-modifiers 以及现有的 bind 方法.

As it already got mentioned, one really is not in need of real Aspect-oriented Programming in order to solve such tasks in JavaScript. But this language might deserve some more standardized method-modifiers in addition to the already existing bind method.

请查看我最近关于此事的 2 篇帖子:

Please check back with my 2 most recent posts on this matter:

...以及如何在需要修改标识字符串Function #1"的情况下实现它;自动?

... and how to implement it with the need of modifying the identification string "Function #1" automatically?

不需要,因为控制台的 time/timeEnd 功能只需要用于测量时间的相同入口和出口点(如秒表的开始/停止触发器).因此,您可以准确了解当前正在运行/测量的函数/方法的引用.

One does not need to since the console's time / timeEnd functionality only has to have identical entry and exit points for measuring time (like the start/stop trigger of a stopwatch). So one gets along with exactly the reference of the function/method one is currently running/measuring.

为了解决给定的任务,我只建议 around 而不是 beforeafter 前者产生较少的开销.下一个代码块示例性地显示了一个可能的原型实现.它也是后面例子的基础这最终可能会解决 OP 的任务.

In order to solve the given task I will suggest around only instead of both before and after for the former generates less overhead. The next code block exemplarily shows a possible prototypal implementation. It also is the base for the afterwards following example that finally might solve the OP's task.

(function (Function) {
  var
    isFunction = function (type) {
      return (
           (typeof type == "function")
        && (typeof type.call == "function")
        && (typeof type.apply == "function")
      );
    },
    getSanitizedTarget = function (target) {
      return ((target != null) && target) || null;
    }
  ;
  Function.prototype.around = function (handler, target) { // [around]
    target  = getSanitizedTarget(target);

    var proceed = this;
    return (isFunction(handler) && isFunction(proceed) && function () {

      return handler.call(target, proceed, handler, arguments);

    }) || proceed;
  };
}(Function));

下一个示例考虑到 method-modification 本质上依赖于绑定到对象的功能.它不仅仅是函数包装.为了为了不丢失方法正在操作的 context,必须委托 context/在所有操作中作为 target 传递.

The next example takes into account that method-modification essentially relies on functionality that is bound to an object. It is not just function wrapping. In order to not loose the context a method is operating on, context has to be delegated / passed around as target throughout all operations.

对于这个例子没有修改 calculate 因为它没有绑定到一个对象但它修改了trigger.

For this the example does not modify calculate since it is not bound to an object but it modifies trigger instead.

var testObject = {

  calculate: function (hugeInteger) {
    var
      i = hugeInteger,
      k = 0
    ;
    while (i--) {
      k++;
    }
    return k;
  },
  trigger: function (hugeInteger) {
    this.result = this.calculate(hugeInteger);
  },
  result: -1
};

console.log("testObject.result : ", testObject.result);

console.log("testObject.trigger(Math.pow(2, 26)) : ", testObject.trigger(Math.pow(2, 26))); // takes some time.
console.log("testObject.result : ", testObject.result);

console.log("testObject.someTrigger(0) : ", testObject.trigger(0)); // logs immediately after.
console.log("testObject.result : ", testObject.result);


testObject.trigger = testObject.trigger.around(function (proceed, interceptor, args) {

  // before:
  console.time(proceed);

  // proceed:
  proceed.apply(this, args);

  // after:
  console.timeEnd(proceed);

}, testObject); // omitting the 2nd argument - the [target] object - might break code that did work before.


console.log("testObject.trigger(Math.pow(2, 26)) : ", testObject.trigger(Math.pow(2, 26)));
console.log("testObject.result : ", testObject.result);

.as-console-wrapper { min-height: 100%!important; top: 0; }

<script>
  (function (Function) {
    var
      isFunction = function (type) {
        return (
             (typeof type == "function")
          && (typeof type.call == "function")
          && (typeof type.apply == "function")
        );
      },
      getSanitizedTarget = function (target) {
        return ((target != null) && target) || null;
      }
    ;
    Function.prototype.around = function (handler, target) { // [around]
      target  = getSanitizedTarget(target);

      var proceed = this;
      return (isFunction(handler) && isFunction(proceed) && function () {

        return handler.call(target, proceed, handler, arguments);

      }) || proceed;
    };
  }(Function));
</script>

这篇关于使用 AOP 调用方法前后的 Javascript 控制台输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆