任务:我需要以递归方式遍历json对象并对密钥进行某些更改。我将处理具有不同深度和不同尺寸的物体。当函数命中其值为对象的键时,将再次在该对象上调用它。
问题1。:将此作为同步函数,我注意到大型json对象返回不完整。使用异步库,async.forEach
解决了处理长任务的问题,并且仅在完成时返回,但是......
问题2。:async函数在递归调用时似乎失去了并发性(?)(在代码片段中指出)。
为了测试这个想法,我删除了递归函数调用并且它工作了(但没有递归),并且我得到了一个回调。当我重新添加函数调用时,我得到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);
});
}
&#13;
编辑:很难在评论中格式化,所以:
@Laksh和@Suhail:我尝试了你的建议和相同的结果。如果我从if
条件中删除回调,async.forEach
仍然会确认它已经处理了顶级键(我认为)。
例如,假设我有3个顶级键,其中一个有嵌套对象:
[key1] (no callback, do recursion)
--[subKey1]
--[subKey2]
[key2] (callback)
[key3] (callback)
async.forEach
仍在寻找针对key1采取的操作的回调。我有这个吗?
答案 0 :(得分:0)
由于您在此处使用递归函数,因此无需在if条件内调用callback()
。
这是因为如果整个递归堆栈完成特定的callback()
,您的递归调用将返回到现有的obj[key]
。
递归函数仅在基本条件为真时返回,在您遇到条件失败的情况下,它将自动从else块调用callback()
。