Javascript:异步遍历列表的列表

Javascript: Traverse lists of lists asynchronously

本文关键字:列表 遍历 异步 Javascript      更新时间:2023-09-26

我正在尝试遍历一个javascript列表。

目标是将每个项传递给函数并处理它异步。但是它不工作:

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);
})

代码在300处停止,而不是处理树的其余部分。

如果我取消上面那两行注释,我可以打印所有项,但是它们不要表现出有秩序。我该如何解决这个问题?

此解决方案使用第二个可选回调,允许子迭代函数tree向父函数tree发出信号,以便在子函数完成后继续运行。

按预期运行,每次叶子元素迭代之间延迟1秒。

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);
});

应该可以:

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);
})