Reputation: 651
I'm trying to traverse a javascript lists of lists.
The goal is to pass each item into a function and process it asynchronously. However it isn't working:
var tree = function (data, callback) {
var data_position = 0;
var iterate = function () {
if (data_position<data.length) {
if (Array.isArray(data[data_position])) {
tree(data[data_position], callback);
// If I uncomment these it will show all items but not ordered
//data_position++;
//iterate();
} else {
callback(data[data_position++], iterate);
}
}
}
iterate();
}
tree([1, 2, [100, 200, 300], 3, 4, 5, 6, 7, 8, 9], function (item, iterate) {
setTimeout(function(){
console.log('Item: ' + item);
iterate();
}, 1000);
})
The code stops at 300 instead of processing the rest of the tree.
If I uncomment those 2 lines above, I can print all items, but they don't show ordered. How can I fix this?
Upvotes: 1
Views: 64
Reputation: 3573
This solution uses a second optional callback that allows the child iterating function tree
to signal the parent tree
to continue running once the child is finished.
It runs as expected with 1 second delay between every leaf element iteration.
var tree = function (data, callback, done) {
var data_position = 0;
var iterate = function () {
if (data_position<data.length) {
if (Array.isArray(data[data_position])) {
tree(data[data_position++], callback, function() { iterate(); });
} else {
callback(data[data_position++], iterate);
}
} else if (done) {
done();
}
}
iterate();
};
tree([1, 2, [100, 200, 300], 3, 4, 5, 6, 7, 8, 9], function (item, iterate) {
setTimeout(function(){
console.log('Item: ' + item);
iterate();
}, 1000);
});
Upvotes: 2
Reputation: 1211
This should work:
var tree = function (data, callback) {
var data_position = 0;
var iterate = function () {
if (data_position<data.length) {
if (Array.isArray(data[data_position])) {
tree(data[data_position], callback);
}
callback(data[data_position++], iterate);
}
}
iterate();
}
tree([1, 2, [100, 200, 300], 3, 4, 5, 6, 7, 8, 9], function (item, iterate) {
setTimeout(function(){
if(!Array.isArray(item)) console.log('Item: ' + item);
iterate();
}, 1000);
})
Upvotes: 0