为了账号安全,请及时绑定邮箱和手机立即绑定

永远不会解决的承诺会导致内存泄漏吗?

永远不会解决的承诺会导致内存泄漏吗?

犯罪嫌疑人X 2019-12-25 10:23:27
我有一个Promise。我创建它是为了取消AJAX请求(如果需要)。但是,由于我不需要取消该AJAX,因此我从未解决过该问题,因此AJAX已成功完成。简化的代码段:var defer = $q.defer();$http({url: 'example.com/some/api', timeout: defer.promise}).success(function(data) {    // do something});// Never defer.resolve() because I don't need to cancel that ajax. What happens to this promise after request?从来没有解决过这样的承诺会导致内存泄漏吗?您对如何管理Promise生命周期有任何建议吗?
查看完整描述

3 回答

?
繁星淼淼

TA贡献1775条经验 获得超11个赞

好吧,我假设您没有对其进行明确引用,因为这将迫使它保持分配状态。


我能想到的最简单的测试实际上是分配许多诺言而不是解决它们:


var $q = angular.injector(["ng"]).get("$q");

setInterval(function () {

    for (var i = 0; i < 100; i++) {

        var $d = $q.defer();

        $d.promise;

    }

}, 10);

然后观察堆本身。正如我们在Chrome分析工具中所看到的那样,这会积聚所需的内存以分配100个Promise,然后整个JSFIddle页面的 “停留时间”不到15兆字节。


另一方面,如果我们看一下$q源代码


我们可以看到,没有从全局角度引用任何特定的Promise,而仅是从Promise到其回调。该代码非常易读和清晰。让我们看看如果您确实从回调中引用了Promise。


var $q = angular.injector(["ng"]).get("$q");

console.log($q);

setInterval(function () {

    for (var i = 0; i < 10; i++) {

        var $d = $q.defer();

        (function ($d) { // loop closure thing

            $d.promise.then(function () {

                console.log($d);

            });

        })($d);

    }

}, 10);


因此,在初始分配之后-似乎也能够处理该问题:)


如果让他的上一个示例再运行几分钟,我们还可以看到一些有趣的GC模式。我们可以看到它需要一些时间-但它能够清除回调。


简而言之-至少在现代浏览器中-您不必担心未解决的承诺,只要您没有对它们的外部引用


查看完整回答
反对 回复 2019-12-25
?
青春有我

TA贡献1784条经验 获得超8个赞

这就是我的想法。因此,问题是“永不解决的诺言会导致内存泄漏吗?” 对于将回调传递给Promise的常见用例,答案是肯定的。您的答案中的这一行似乎与以下事实矛盾:“如果让他的上一个示例再运行几分钟,我们还可以看到一些有趣的GC模式。我们可以看到它花了一段时间-但它能够清理回调。 ” 抱歉,如果我要学步又挑剔,我只是想确保自己理解这一点。

查看完整回答
反对 回复 2019-12-25
  • 3 回答
  • 0 关注
  • 892 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信