使用AOP调用方法前后的Javascript控制台输出
我想测量方法的计算时间 一个好方法是()与使用AOP调用方法前后的Javascript控制台输出,javascript,aop,sapui5,function-composition,modifier,Javascript,Aop,Sapui5,Function Composition,Modifier,我想测量方法的计算时间 一个好方法是()与console.time('Function#1')和控制台.timeEnd('Function#1') 我的想法是在生命周期方法上添加这些控制台输出。在本例中,使用类似SAPUI5的createContent:funtion(){}方法 这应该可以通过AOP使用before()和after()来运行时间计数 您会建议哪种AOP框架,以及如何实现它,同时需要自动修改标识字符串“Function#1”?实际上不需要Javascript中的方面,因为您可以随
console.time('Function#1')代码>和控制台.timeEnd('Function#1')代码>
我的想法是在生命周期方法上添加这些控制台输出。在本例中,使用类似SAPUI5的createContent:funtion(){}代码>方法
这应该可以通过AOP使用before()
和after()
来运行时间计数
您会建议哪种AOP框架,以及如何实现它,同时需要自动修改标识字符串“Function#1”?实际上不需要Javascript中的方面,因为您可以随时更改任何对象的任何函数。JavaScript原型允许您在运行时操纵对象所有实例的方法实现。这里有两种方法可以实现您的计划
您可以使用通用包装器函数:
var measureId = 0;
var fnMeasureFunction = function(fnToMeasure) {
console.time('measure'+ measureId);
fnToMeasure();
console.timeEnd('measure'+ measureId);
measureId++;
}
诚然,这要求您更改实际代码
对于静态函数或属于原型的函数,您也可以从外部执行类似操作,而无需对现有代码进行任何更改:
// any static function
var measureId = 0;
var fnOriginalFunction = sap.ui.core.mvc.JSViewRenderer.render;
sap.ui.core.mvc.JSViewRenderer.render = function() {
console.time('measure'+ measureId);
fnOriginalFunction.apply(this, arguments);
console.timeEnd('measure'+ measureId);
measureId++;
}
// any prototype function
var fnOriginalFunction = sap.m.Button.prototype.ontouchstart;
sap.m.Button.prototype.ontouchstart= function() {
console.time('measure'+ measureId);
fnOriginalFunction.apply(this, arguments);
console.timeEnd('measure'+ measureId);
measureId++;
}
这应该可以通过AOP使用before()和after()来运行时间计数
正如已经提到的,一个人实际上并不需要真正的面向方面编程
为了解决JavaScript中的此类任务。但这种语言可能需要更标准化一些
除了已经存在的bind
方法之外,还有方法修饰符
请查看我最近关于这个问题的两篇帖子:
。。。如何在需要自动修改标识字符串“Function#1”的情况下实现它
由于控制台的time
/timeEnd
功能只需要
测量时间的相同入口和出口点(如秒表的启动/停止触发器)。
因此,我们可以准确地理解当前正在运行/测量的函数/方法的引用
为了解决给定的任务,我将仅建议在
前后进行,而不是在
之前进行和
前者的后
生成的开销较小。下一个代码块示例性地显示了
可能的原型实现。它也是下面示例的基础
这最终可能解决OP的任务
(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));
下一个示例考虑了方法修改基本上依赖于
绑定到对象的功能。这不仅仅是功能包装。整齐
为了不丢失方法正在操作的上下文,必须委托上下文/
在所有操作中作为target
传递
因此,该示例不修改计算
,因为它未绑定到对象
但它改为修改触发器
var testObject={
计算:函数(hugeInteger){
变量
i=hugeInteger,
k=0
;
而(我--){
k++;
}
返回k;
},
触发器:函数(hugeInteger){
this.result=this.calculate(hugeInteger);
},
结果:-1
};
log(“testObject.result:”,testObject.result);
log(“testObject.trigger(Math.pow(2,26)):”,testObject.trigger(Math.pow(2,26));//需要一些时间。
log(“testObject.result:”,testObject.result);
console.log(“testObject.someTrigger(0):”,testObject.trigger(0));//之后立即记录日志。
log(“testObject.result:”,testObject.result);
testObject.trigger=testObject.trigger.around(函数(继续、拦截器、args){
//之前:
控制台。时间(继续);
//进行:
继续。应用(本,args);
//之后:
控制台。时间结束(继续);
},testObject);//省略第二个参数[target]对象可能会破坏以前可以工作的代码。
log(“testObject.trigger(Math.pow(2,26)):”,testObject.trigger(Math.pow(2,26));
log(“testObject.result:”,testObject.result)代码>
.as控制台包装{最小高度:100%!重要;顶部:0;}
(功能(功能){
变量
isFunction=函数(类型){
返回(
(typeof type==“函数”)
&&(typeof type.call==“函数”)
&&(typeof type.apply==“函数”)
);
},
getSanitizedTarget=函数(目标){
返回((target!=null)&&target)| null;
}
;
Function.prototype.around=函数(处理程序,目标){/[around]
目标=getSanitizedTarget(目标);
var继续=这个;
返回(isFunction(处理程序)和isFunction(继续)和函数(){
调用(目标、继续、处理程序、参数);
})| |继续;
};
}(功能);