gpt4 book ai didi

javascript - 进行嵌套/递归计算时如何运行事件循环?

转载 作者:行者123 更新时间:2023-12-05 00:28:46 31 4
gpt4 key购买 nike

如何使用 setTimeout() 中断计算和释放的常见示例似乎依赖于浅(1-深)调用堆栈。
但是,当您进行深度嵌套或相互递归的计算(如树搜索)并且堆栈中有大量上下文时,该怎么办?
如果 JavaScript 有一个可以封装“当前延续”(即:当前调用堆栈)的函数,将其放入事件队列和 ,那将是理想的。返回/抛出/回调到顶层事件循环 . (因此其他事件将运行,然后计算将在它停止的地方重新启动)。我正在寻找一种简单的方法来让函数自动“让出”控制,让事件 catch ,然后将控制返回到我们停止的地方。最好不要重写调用链中的每个函数。
但我找不到任何可以做到这一点的东西......

  • 作为一名退休的策划者,我期待像 call/cc 这样的东西,但没有找到它。
  • setTimeout()将返回控制[但只升级 1 级],并重新启动一些其他计算(但不是隐式的当前继续,除非我们将整个应用程序提交给 CPS...)
  • 'yield' 将框住当前函数/堆栈帧的延续,因此可以重新启动它,
    但是 yield 只返回一个级别。 ( yield 类似于:return/cc vs call/cc)
  • 'throw' 可以向上抛出堆栈,但无法重新启动
    从 throw 点计算(据我所知;需要类似“ throw /cc”)

  • 我已经使用'yield'构建了一个半解决方案,但它很笨拙,要求堆栈上的每个函数(a)被声明为'function *'并且(b)在每次调用周围包含样板代码到下一个函数[传播产量并使用 next() 重新启动]
    问:有没有办法在 JavaScript 中实现这一点,而无需检测调用链上的所有函数?

    最佳答案

    我将添加一个您似乎没有考虑过的替代解决方案:Promise s。或者更具体地说,用于处理 promise 的语法糖:async/await .
    使用 Promise实现您的allowEventLoop() 很简单功能:

    function allowEventLoop () {
    return new Promise((ok,fail) => setTimeout(ok,0));
    }
    现在,每当您需要暂停当前计算并运行事件循环时,您只需要调用:
    await allowEventloop();
    这是一个使用上述函数的简单递归下降解析器的示例(注意:Js 中的代码,但在 Ts 中执行此操作应该很简单):
    async function drawTree(node, indent) {
    if (!indent) indent = 0;

    let tree = `${'\t'.repeat(indent)}${node.name}\n`;

    await allowEventloop();

    if (node.children) {
    for (let child of node.children) {
    tree += await drawTree(child, indent+1);
    }
    }

    return tree;
    }
    如您所见,递归函数的逻辑几乎没有变化。它看起来与普通同步版本几乎完全相同。主要区别在于您的函数现在返回 Promise结果。
    使用 async/await 时你基本上跳过了调用堆栈。相反,您真正在做的是使用 .then() 的链。来电。所以实际上调用堆栈仍然是 1 级深度,但您正在动态构建一个复杂的 .then()链。在实践中,它感觉就像通常的基于调用堆栈的递归。
    要执行的函数队列由 Promises 不可见地处理 - 这本质上是一种用于处理连续传递样式 (CPS) 代码的设计模式。这类似于调用堆栈如何管理要返回的函数队列。这就是为什么感觉一样。

    关于javascript - 进行嵌套/递归计算时如何运行事件循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71963376/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com