Javascript 方法代理和 AngularJS
Javascript method proxy and AngularJS
我正在使用 AngularJS 并且在访问相同的基于方法的变量时,即 {{someValue()}}
,我意识到每次通过 $apply 刷新范围时都会调用该方法。由于我的方法是确定性的,即只依赖于我知道的几个输入,我怎样才能做一个代理来避免多次处理相同的数据?
[更新]
我最近发现了 memoize(understore 和 lodash)函数,它以类似的方式运行:https://lodash.com/docs#memoize
下面是我之前的回答:
我解决了构建 MethodProxy 对象的问题
MethodProxy 将回调作为参数(要代理的方法)
我们通过代理调用方法,如果参数完全相同,代理将return缓存的结果,否则它会使用回调更新其值,存储和return结果。
注意:以下解决方案使用 _.isEqual
比较参数,它是 UnderscoreJS or Lodash if you need a slow (approximatively 3 times slower 的一部分)但临时比较器只定义
_ = {isEqual:function(a,b){return JSON.stringify(a)===JSON.stringify(b)}};
但是,我再次强烈推荐使用经过优化的 Lodash,这里是 MethodProxy:
function MethodProxy(callback_)
{
var lastArguments = undefined;
var callback = callback_;
var cachedAnswer = undefined;
this.call = function()
{
if (_.isEqual(lastArguments, arguments))
{
return cachedAnswer;
}
else
{
lastArguments = arguments;
cachedAnswer = callback.apply(this, arguments);
return cachedAnswer;
}
};
}
用法示例:
var test = new MethodProxy(function(value)
{
console.log("The method is called");
return value;
})
test.call("hello");// prints "The method is called" then return "hello"
test.call("hello");// returns "hello" (the cached value)
test.call("world");// prints "The method is called" then return "world"
如何在 angular 中使用它?
在 JS 中:
function myDataProxy = new MethodProxy(function(arg1, arg2)
{
// your expensive CPU method
return arg1+arg2;
})
$scope.myData = function()
{
var value1 = $scope.valueWhichCanChangeOrNot;
var value2 = $scope.anotherValueWhichCouldHaveBeenUpdated;
return myDataProxy.call(value1, value2);
}
在 HTML 中:
{{myData()}}
限制:
该方法必须是确定性的,即在给定其输入参数的情况下应始终给出相同的输出
如果参数很大,可能需要一些时间来比较它们。
其他:
您可以从函数本身捕获值,只需要将检查它们是否更改的相关参数发送到调用方法。
我正在使用 AngularJS 并且在访问相同的基于方法的变量时,即 {{someValue()}}
,我意识到每次通过 $apply 刷新范围时都会调用该方法。由于我的方法是确定性的,即只依赖于我知道的几个输入,我怎样才能做一个代理来避免多次处理相同的数据?
[更新] 我最近发现了 memoize(understore 和 lodash)函数,它以类似的方式运行:https://lodash.com/docs#memoize
下面是我之前的回答:
我解决了构建 MethodProxy 对象的问题
MethodProxy 将回调作为参数(要代理的方法)
我们通过代理调用方法,如果参数完全相同,代理将return缓存的结果,否则它会使用回调更新其值,存储和return结果。
注意:以下解决方案使用 _.isEqual
比较参数,它是 UnderscoreJS or Lodash if you need a slow (approximatively 3 times slower 的一部分)但临时比较器只定义
_ = {isEqual:function(a,b){return JSON.stringify(a)===JSON.stringify(b)}};
但是,我再次强烈推荐使用经过优化的 Lodash,这里是 MethodProxy:
function MethodProxy(callback_)
{
var lastArguments = undefined;
var callback = callback_;
var cachedAnswer = undefined;
this.call = function()
{
if (_.isEqual(lastArguments, arguments))
{
return cachedAnswer;
}
else
{
lastArguments = arguments;
cachedAnswer = callback.apply(this, arguments);
return cachedAnswer;
}
};
}
用法示例:
var test = new MethodProxy(function(value)
{
console.log("The method is called");
return value;
})
test.call("hello");// prints "The method is called" then return "hello"
test.call("hello");// returns "hello" (the cached value)
test.call("world");// prints "The method is called" then return "world"
如何在 angular 中使用它?
在 JS 中:
function myDataProxy = new MethodProxy(function(arg1, arg2)
{
// your expensive CPU method
return arg1+arg2;
})
$scope.myData = function()
{
var value1 = $scope.valueWhichCanChangeOrNot;
var value2 = $scope.anotherValueWhichCouldHaveBeenUpdated;
return myDataProxy.call(value1, value2);
}
在 HTML 中:
{{myData()}}
限制: 该方法必须是确定性的,即在给定其输入参数的情况下应始终给出相同的输出 如果参数很大,可能需要一些时间来比较它们。
其他: 您可以从函数本身捕获值,只需要将检查它们是否更改的相关参数发送到调用方法。