【发布时间】:2018-11-04 03:24:28
【问题描述】:
对于线程中的 cmets 树,我有以下数据结构。此结构包含在单个对象中。
comment {
id: 1,
text: 'foo',
children: [
comment {
id: 2,
text: 'foo-child',
children: []
},
comment {
id: 3,
text: 'foo-child-2',
children: []
}
]
},
comment {
id: 4,
text: 'bar',
children: []
}
这是由后端 API 提供的,没有问题。我想要做的是递归地探索这棵树,并且对于每个节点(根节点或子节点)我想执行一个 API 调用并获取一些额外的数据为每个单个节点,拍一些额外的属性,并返回整个树以及添加到每个节点的新键。
function expandVoteData(comments) {
return new Promise((resolve, reject) => {
let isAuth = Auth.isUserAuthenticated();
// 'this' is the vote collection
async.each(comments, (root, callback) => {
// First get the vote data
async.parallel({
votedata: function(callback) {
axios.get('/api/comment/'+root.id+'/votes').then(votedata => {
callback(null, votedata.data);
});
},
uservote: function(callback) {
if(!isAuth) {
callback(null, undefined);
} else {
axios.get('/api/votes/comment/'+root.id+'/'+Auth.getToken(), { headers: Auth.getApiAuthHeader() }).then(uservote => {
callback(null, uservote.data); // Continue
});
}
}
}, function(error, data) {
if(error) {
console.log('Error! ', error);
} else {
// We got the uservote and the votedata for this root comment, now expand the object
root.canVote = isAuth;
root.totalVotes = data.votedata.total;
root.instance = 'comment';
if(data.uservote !== undefined) {
root.userVote = data.uservote;
}
if(root.children && root.children.length > 0) {
// Call this function again on this set of children
// How to "wrap up" this result into the current tree?
expandVoteData(root.children);
}
callback(); // Mark this iteration as complete
}
});
}, () => {
// Done iterating
console.log(comments);
resolve();
});
})
}
它的作用是:接受一个 'cmets' 参数(它是整个树对象),创建一个 Promise,遍历每个叶节点,并在异步请求中执行相应的 API 调用。如果叶节点有任何子节点,则对每个子节点重复该函数。
理论上这在同步世界中可以完美运行,但我需要做的是在每个节点都经过处理后获取新树以进行进一步处理,作为单个对象,就像它作为输入一样。事实上,我为树中的每个单独节点获得了多个控制台打印,证明代码按照编写的方式工作......虽然我不想要单独的打印,我想将整个结果集包装在一个对象中.理想情况下,函数应该这样调用:
expandVoteData(comments).then(expanded => {
// yay!
});
关于如何执行此操作的任何提示?提前谢谢你。
【问题讨论】:
-
不要将 Promise 与
async.js一起使用。 -
为什么不建议将 Promise 与 async.js 一起使用?
-
因为回调样式不能很好地与 promise 语法一起使用。来回的转换导致到处都是微妙的错误。例如,您实际上并没有在任何地方处理错误。
标签: javascript node.js asynchronous recursion tree