【问题标题】:How can I chain many sequential promises while limiting stack depth? [duplicate]如何在限制堆栈深度的同时链接许多顺序承诺? [复制]
【发布时间】:2014-03-22 01:27:55
【问题描述】:

我正在尝试发送网络数据。本质上,我使用的库对消息大小有 16kb 的限制,因此我必须分解较大的消息并将它们分块发送。我的代码的真正简化版本可能如下所示:

function sendInChunks(buffers) {
    send(buffers.shift()).then(sendInChunks.bind(undefined, buffers));
}

通过这样的递归实现,我可以发送的数据量受到代码运行平台的堆栈深度限制的限制。我想知道是否有一种方法可以在不受堆栈深度限制的情况下发送我的数据?

注意:在我现在的实际实现中,我实际上是在调用 send 后使用相互递归进行一些检查。在这两个函数中还使用了更高范围的一些状态,但希望不会有太大变化。

编辑:我正在使用 es6 承诺。

【问题讨论】:

  • 您能否说明您使用的是哪种 ES6 Promises 实现?如果此模式受堆栈深度限制,则存在错误。

标签: javascript promise stack-overflow


【解决方案1】:

Promises 是异步的,这意味着它实际上不是递归调用;它更像是一个循环。下面是一个简单的例子,它也不是递归的。

function send(buffers){
    buffers.shift();
    if (buffers.length) {
        setTimeout(send.bind(null, buffers), 10);
    }
}

send(buffers);

当我们调用send 时,它会移动一个缓冲区,然后可能会注册一个超时,然后返回。因为它没有调用自己就返回,所以它不是递归的。

附注:在 ES6 中,有适当的尾调用优化;这意味着递归限制不会经常成为问题。

【讨论】:

  • 太棒了!这是否记录在某处?
  • 它是几个东西的组合,也是常见的promise实现; ES6 规范草案;和承诺/A+。我必须挖掘所有这些才能找到确切的报价。字里行间也需要一点阅读。
【解决方案2】:

我可以发送的数据量受到代码运行平台的堆栈深度限制

没有。由于 Promise 是异步解决的,因此每次回调都会使用一个新的堆栈帧,您不会遇到堆栈溢出。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-14
    相关资源
    最近更新 更多