Łuk*_*man 6 javascript ajax jquery angularjs
考虑Angular Js中相当标准方法的这个例子,它更新了视图:
$scope.fetchResults = function() {
// Some local variable that will cause creation of closure
var hugeData = serviceX.getMilionRecords();
// Any call to any resource with success and error handlers.
$http({
method: "GET",
url: "/rest-api/bulk-operation-x",
params: { someParam: hugeData.length }
}).success( function () {
var length = hugeData.length;
$scope.reportToUser("Success, that was " + length + " records being processed!";
}).error( function () {
var length = hugeData.length;
$scope.reportToUser("Something went wrong while processing " + length + " records... :-(";
});
};
Run Code Online (Sandbox Code Playgroud)
这当然是假设的例子,但很好地显示了模式,可以将其描述为从AJAX回调中重用局部变量.
当然,在两个处理程序(success和error)中,我们创建一个闭包,hugeData它直接从回调处理程序引用.
我的问题是:由于AJAX调用的结果只能成功或失败,重用这段代码会导致内存泄漏吗?我会回答"是",但我无法在本地测试中可靠地证明这一点.
我想要一些更有经验的大师为我解释这个.我喜欢每天与Angular合作的人的回复,但欢迎任何jquery回复.
一旦将调用结果$http()(或有权访问 的任何对象或函数hugeData)返回到 的外部作用域,就会发生内存泄漏fetchResults。
对于您的代码,没有什么大的东西直接暴露在 之外fetchResults,并且调用的结果$http()将一直存在,直到成功或失败,然后调用相应的回调,最后进行 GC。
有关见解,请参阅:http://jibbering.com/faq/notes/closures/#clIdRes
\n\n正如 @\xc5\x81ukaszBachman 所观察到的,这并不能保证不存在内存泄漏。任何对大对象或范围内具有大对象的回调的悬空引用都会导致灾难。
\n\n那么,让我们检查一下$q实现($http基于$q)。
如果您检查https://github.com/angular/angular.js/blob/master/src/ng/q.js#L191,您可以看到resolve()deferred 的方法首先将注册的回调列表复制到变量中本地方法:
var callbacks = pending;\nRun Code Online (Sandbox Code Playgroud)\n\n随后使外部pending(在该defer级别定义的)无效
pending = undefined;\nRun Code Online (Sandbox Code Playgroud)\n\n然后,在下一个时钟周期,执行回调。由于回调的参数本身可能是延迟的(进一步增加执行延迟),事情可能会变得复杂,但最多可能会进入无限循环。(这并不好笑!)。如果你足够幸运没有进入循环,那么在某个时刻回调数组就会耗尽,然后就没有任何对回调列表的引用,因此它可用于 GC。
\n\n但。
\n\n如果你强迫他们这样做,事情可能会出错。
\n\n您可以在回调中使用arguments.callee。
\n\n你也可以把啤酒扔到键盘上。
\n\n如果你从窗户跳出去,除非你住在一楼,否则你很可能会受伤。
\n\n祝 Ecma 脚本编写愉快!
\n| 归档时间: |
|
| 查看次数: |
881 次 |
| 最近记录: |