JavaScript承诺在未被拒绝或解决时是否会造成内存泄漏?

Yan*_*hon 7 javascript memory-leaks es6-promise

我需要在"并行"中执行异步函数,并以最佳结果继续执行程序.因此我写了这样的东西:

var p = [];

for (var i = 0; i < 10; ++i) (function (index) {
  p.push(new Promise(function (resolve, reject) {
    setTimeout(function () {
      var success = Math.random() > 0.7;

      console.log("Resolving", index, "as", success ? "success" : "failure");

      success && resolve(index);
    }, Math.random() * 5000 + 200);
  }));
})(i);

Promise.race(p).then(function (res) {
  console.log("FOUND", res);
}).catch(function (err) {
  console.log("ERROR", err);
});
Run Code Online (Sandbox Code Playgroud)

现在,我想知道在使用承诺时这是否是一个好习惯?是不是更频繁地解决或拒绝它们然后任何事情造成内存泄漏?他们每次最终都是GC吗?

jib*_*jib 3

导致内存泄漏的唯一原因是因为它p是全局变量。p = null;在最后设置,或避免使用全局变量:

var console = { log: function(msg) { div.innerHTML += msg + "<br>"; }};

Promise.race(new Array(10).fill(0).map(function(entry, index) {
  return (function(index) {
    return new Promise(function(resolve) {
      setTimeout(function() {
        var success = Math.random() > 0.7;
        console.log((success? "R":"Not r") + "esolving "+ index +".");
        success && resolve(index);
      }, Math.random() * 5000 + 200);
    });
  })(index);
})).then(function (res) {
    console.log("FOUND: " + res);
}).catch(function (err) {
    console.log("ERROR: " + err);
});
Run Code Online (Sandbox Code Playgroud)
<div id="div"></div>
Run Code Online (Sandbox Code Playgroud)

当没有任何内容保留 Promise 时,即当您的 JS 和浏览器(此处setTimeout)不再引用它们时,Promise 就会被垃圾和循环收集。

一旦一个条目p成功或某件事失败(以较早者为准),并且setTimeout将在 5.2 秒后放弃所有内容。然后,JavaScript 会愉快地对 Promise 进行垃圾收集,无论它们是否已被解决、被拒绝或两者都没有。无害。

您唯一要避免的是垃圾收集被拒绝的Promise,因为这可能会触发浏览器警告,因为它表明存在 Web 编程错误。

当然,有 30% 的可能性它们都无法解决,在这种情况下,这将泄漏(直到您关闭选项卡)。

这是好的设计吗?

我认为这取决于函数正在做什么。如果它们很轻,那么我认为没有问题。如果他们正在进行繁重的计算或有副作用,那么他们希望提供一些 API 来取消操作,以帮助节省资源。