[
{
name: 'test1',
fields: [
{
name: 'test11',
fields: [
{
name: 'test111',
fields: [
{
name: 'test1111'
}
]
}
]
}
]
},
{
name: 'test2',
fields: [
{
name: 'test21'
},
{
name: 'test22'
}
]
}
我想在nodejs中以递归方式处理上面数组中的字段名称。由于nodejs异步行为,循环无法正常工作。
答案 0 :(得分:1)
您需要定义“流程”。如果它是同步的东西,那么显然没什么特别的:
function visit (visitor, obj) {
if (Array.isArray(obj)) return obj.forEach(visit.bind(null, visitor))
if (Array.isArray(obj.fields)) obj.fields.forEach(visit.bind(null, visitor))
visitor(obj)
}
function visitor (obj) {
console.log(obj.name)
}
visit(visitor, data)
如果在visitor
中你想要异步,那么有很多选择。假设您想要进程第一个节点的子节点(并行),然后是节点本身:
// the order of arguments is weird, but it allows to use `bind`
function visit (visitor, callback, obj) {
var array
if (Array.isArray(obj)) array = obj
if (Array.isArray(obj.fields)) array = obj.fields
if (!array) return visitor(obj, callback)
// number of pending "tasks"
var pending = array.length
var done = false
function cb () {
// ensure that callback is called only once
if (done) return
if (!--pending) {
done = true
// after all children are done process the node itself
if (!Array.isArray(obj)) return visitor(obj, callback)
//if the whole node is array
callback()
}
}
array.forEach(visit.bind(null, visitor, cb))
}
function visitor (obj, callback) {
process.nextTick(function () {
console.log(obj.name)
callback()
})
}
visit(visitor, after, data)
function after () {
console.log('all done')
}
它基本上是相同的代码,但有回调和一些异步流控制代码。当然,您可以使用async
包。