javascript - 带和不带 sleep 的递归异步

标签 javascript

我有两个版本的异步函数

async function asyncRecurseOne(i){
    try{
        console.log(i)
        i = i +1;
        await asyncRecurseOne(i)
    }catch(ex){
        console.log(ex);
    }
}

asyncRecurseOne(0);
这导致最大调用堆栈大小超过了大约 6300
6246
6247
6248
RangeError: Maximum call stack size exceeded
    at asyncRecurseOne (/home/amit/Projects/NodeJs/MJS/recurse.js:38:17)
    at asyncRecurseOne (/home/amit/Projects/NodeJs/MJS/recurse.js:36:15)
现在在另一个版本中,我使用 sleep 方法执行以下操作
let sleep = (time) => new Promise((resolve) => setTimeout(resolve, time))
async function asyncRecurseTwo(i){
    try{
        console.log(i)
        i = i +1;
        await sleep(100);
        await asyncRecurseTwo(i)
    }catch(ex){
        console.log(ex);
    }
}
而且这个函数没有给出最大的调用堆栈大小来解决这个问题,我在我的系统上运行直到数字 20000 被记录。
第二个函数如何在不达到最大堆栈大小问题的情况下继续执行?

最佳答案

async函数同步执行,直到它们到达 await ,此时他们返回一个 promise 。您的第一段代码在这一行只有等待:

await asyncRecurseOne(i)
要评估这条线,它需要调用 asyncRecurseOne , 得到返回值,然后才会await .所以它会同步递归,下一次通过函数会做同样的事情,建立一个越来越大的调用堆栈,直到你得到异常。它永远不会到达await .
你的其他情况没有这个问题。它使它成为这一行:
await sleep(100);
sleep 创建并返回一个 promise 。然后它击中await ,所以你的函数返回一个自己的 promise 。没有增加调用堆栈。 100 毫秒后,它恢复并递归,但是这个新的递归具有相同的中断,因此调用堆栈不会继续增长。

关于javascript - 带和不带 sleep 的递归异步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67606959/

相关文章:

javascript - 设置数字格式始终显示小数点后 2 位

javascript - 如何在 React 中的 GraphQL 突变组件中包含的按钮上有多个 onClick 事件

javascript - 引导关闭 Canvas 菜单点击时折叠

javascript - 通过 Javascript 的强制 CSS 规则被部分应用

javascript - 自动从 html 下拉列表中调用 javascript 函数

javascript - 如何在 javascript/jquery 中解压缩 bzip2 数据?

javascript - 背景颜色改变onclick重构

javascript - 匿名函数被认为是有害的?

javascript - stackedgroupedChart 中的 nvd3 双 X 轴

javascript - Vue.js 中的 {{ name }} 和 {{{ name }}} 有什么区别