【问题标题】:Node.js async recursive function with callback带有回调的 Node.js 异步递归函数
【发布时间】:2017-09-27 21:49:47
【问题描述】:

任务:我需要递归遍历一个 json 对象并对键进行某些更改。我将处理不同深度和不同大小的物体。当函数碰到一个值为对象的键时,会在该对象上再次调用它。

问题 1.:作为同步函数执行此操作时,我注意到大型 json 对象返回不完整。使用 async 库,async.forEach 解决了处理长任务并且只在完成时才返回的问题,但是...

问题 2.:async 函数在递归调用时似乎失去了并发性(?)(在代码 sn-p 中指出)。

为了测试这个想法,我删除了递归函数调用,它工作了(但没有递归),我得到了一个回调。当我重新添加函数调用时,我得到 TypeError: results is not a function

这让我认为带有回调的异步 递归函数不会混入节点。有没有办法同时实现?

可能的修复:我可以运行一个单独的函数来计算所有键,并在一个简单的for 循环中使用计数器作为我的控件,而不是让forEach 处理控件。这似乎有点低效,不是吗?

代码如下:

function fixJsonKeys(obj, results) {

    async.forEach(Object.keys(obj), function(key, callback) {

        if (typeof obj[key] == 'object') {
                
            // do stuff to json key, then call the function
            // on the nested object
            
            fixJsonKeys(obj[key]);

            callback();  // <-- how does this work with recursion??

        }

        else {
            
            // do stuff to json key

            callback();
        }

    }, function(err) {

        if (err) return next(err);
        
        // obj keys fixed, now return completed object

        results(obj);

    });
}

编辑:难以在 cmets 中格式化,所以:

@Laksh 和@Suhail:我尝试了你的建议和相同的结果。如果我从if 条件中删除回调,async.forEach 仍然看起来确认它已经处理了顶级键(我认为)。

例如,假设我有 3 个顶级键,其中一个具有嵌套对象:

[key1] (no callback, do recursion)

    --[subKey1]
    --[subKey2]

[key2] (callback)

[key3] (callback)

async.forEach 仍在寻找对 key1 采取的操作的回调。我说的对吗?

【问题讨论】:

  • 你只能在递归的基本情况下回调
  • 只需在if块内递归调用后删除callback
  • @Queenqueg,fixJsonKeys 的输入是什么样的?预期的输出是什么?
  • @Queenqueg,使用async.forEach,因为您的同步方法失败了,这使得这成为XY Problem - 显示您的同步代码问题

标签: node.js asynchronous recursion


【解决方案1】:

由于这里使用的是递归函数,所以不需要在 if 条件内调用callback()

这是因为一旦针对特定obj[key] 的整个递归堆栈完成,您的递归调用将返回到现有的callback()

递归函数仅在基本条件为真时返回,在您的情况下,如果条件失败,它会自动从 else 块调用 callback()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-29
    • 2014-12-18
    • 2016-09-21
    • 2020-02-10
    • 2020-09-29
    • 2023-03-28
    相关资源
    最近更新 更多