在javascript-内存考虑事项中递归构建承诺链

在javascript-内存考虑事项中递归构建承诺链

在……里面这个答案,承诺链是递归构建的。

略为简化,我们有:

function foo() {
    function doo() {
        // always return a promise
        if (/* more to do */) {
            return doSomethingAsync().then(doo);
        } else {
            return Promise.resolve();
        }
    }
    return doo(); // returns a promise}

这可能会导致调用堆栈。一条承诺链-“深”和“宽”。

我预计内存峰值会比执行递归或单独构建承诺链更大。

  • 是这样吗?
  • 有没有人考虑过以这种方式构建链的记忆问题?
  • 记忆消耗在承诺库之间会有所不同吗?


慕娘9325324
浏览 310回答 3
3回答

慕婉清6462132

过早的优化是不好的,找出性能差异的真正方法是测试您的代码,你不应该担心这个问题(我只需要做一次,我已经为至少100个项目做出了承诺)。是这样吗?是这些承诺必须“记住”它们遵循的内容,如果您对10000的承诺执行此操作,您将有一个10000长的承诺链,如果您不这样做,您就不会(例如,使用递归)-对于任何排队流控制,这都是正确的。如果你必须跟踪10000件额外的东西(操作),那么你需要为它保留内存,这需要时间,如果这个数字是一百万,它可能是不可行的。各图书馆的情况各不相同。有没有人考虑过以这种方式构建链的记忆问题?当然,这是一个很大的问题,也是使用类似于Promise.each在像蓝知更鸟这样的图书馆里then能干的链子。为了避免这种风格,我个人在代码中使用了一个快速应用程序,该应用程序只遍历VM中的所有文件-但在绝大多数情况下,这是一个没有问题的问题。记忆消耗在承诺库之间会有所不同吗?是的,非常重要。例如,蓝鸟3.0将不会分配额外的队列,如果它检测到承诺操作已经是异步的(例如,如果它以Promise.Delay开头),并且只会同步执行(因为异步保证已经被保留)。这意味着,我在对第一个问题的回答中所声称的并不总是正确的(但在常规用例中是正确的):除非提供内部支持,否则本机承诺永远无法做到这一点。再说一遍-这并不令人惊讶,因为承诺库之间的差别是数量级的。

POPMUISE

我刚出了一个可能有助于解决问题的黑客:不要在最后一次做递归then,更确切地说,在最后一次做这件事catch,因为catch不在解决链之外。使用您的例子,应该是这样的:function foo() {     function doo() {         // always return a promise         if (/* more to do */) {             return doSomethingAsync().then(function(){                         throw "next";                     }).catch(function(err) {                         if (err == "next") doo();                     })         } else {             return Promise.resolve();         }     }     return doo(); // returns a promise}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript