如何延迟迭代嵌套对象

时间:2013-07-03 19:53:27

标签: javascript callback timeout iteration delay

我无法独自解决这个问题,需要你的帮助。 我正在使用phonegap应用程序中的嵌套骨干对象,并希望将它们全部保存。保存时,我想显示加载动画。保存所有内容后,我想继续下一页/步骤。 我已经实现了这一点,但动画无效,因为我的保存循环阻止了所有UI更新。 (我正在保存到localStorage,而不是通过ajax。)所以我尝试通过在保存每个项目之间插入超时来减慢保存速度。现在保存被延迟了,但是在真正保存所有内容之前,界面会继续到下一页。我的回调似乎设置不正确。

你知道干净嵌套回调的模式吗?

我已将a fiddle that illustrates my problem放在一起。

您可以帮我修复它,以便按正确的顺序创建警报:A1, A2, A3, A4, A5, A6, A7, B1, B2, B3, Everything is finished

提前多多感谢。

如果您不想查看小提琴,请输入以下代码:

var forest = {
    "trees": [{
        "id": "tree A",
            "leaves": [{
            "name": "A1"
        }, {
            "name": "A2"
        }, {
            "name": "A3"
        }, {
            "name": "A4"
        }, {
            "name": "A5"
        }, {
            "name": "A6"
        }, {
            "name": "A7"
        }]
    }, {
        "id": "tree B",
            "leaves": [{
            "name": "B1"
        }, {
            "name": "B2"
        }, {
            "name": "B3"
        }]
    }]
};

var callback = function () {
    alert("Everything is finished");
};

var workOnTree = function (tree, callback) {
    var leaves = tree.leaves;
    var leafCount = 0;
    var delayedAlert = function () {
        alert(leaves[leafCount].name);
        leafCount += 1;
        if (leafCount < leaves.length) {
            setTimeout(delayedAlert, 1000);
        } else {
            if (callback !== undefined && typeof callback == 'function') {
                callback();
            }
        }
    };
    setTimeout(delayedAlert, 1000);
};

var workOnForest = function (forest, callback) {
    var trees = forest.trees;
    var treeCount = 0;
    var delayedExecution = function () {
        if (treeCount == (trees.length - 1)) {
            // for last tree pass callback
            workOnTree(trees[treeCount], callback);
        } else {
            workOnTree(trees[treeCount]);
        }
        treeCount += 1;
        if (treeCount < trees.length) {
            // this gives a delay between the trees
            setTimeout(delayedExecution, 1000);
        }
    };
    setTimeout(delayedExecution, 1000);
};
workOnForest(forest, callback);

3 个答案:

答案 0 :(得分:1)

如果我理解你想要达到的目标,我认为我做了(但我可能错了)你会不会更好地使用Queue模型?

您需要setTimout()基本上只是为了运行UI事件,以便获得更新。这不需要很长,0ms或1ms(只是在优化的情况下)会很好。

我要做的是有一个回调函数,它从你的一个列表中获取一个叶子项,对其进行处理,然后每次如果还有更多的工作要做的话,每次使用setTimeout()重新安排更多的工作。 / p>

这样,您的操作将按顺序进行处理。我不认为你希望它们并行运行,尽管它看起来就像正在发生的那样。所以你的回调也会被序列化。

我知道你已经建立了一个专门用来尽可能简单地证明这个问题的人为例子,但是这看起来有点难以看到你正在尝试做什么,但我对此有所帮助吗?

答案 1 :(得分:0)

我认为你应该使用.sort()方法,你应该在这个方法中添加自己的参数。这些会给你一个想法: How may I sort a list alphabetically using jQuery? http://james.padolsey.com/javascript/sorting-elements-with-jquery/

答案 2 :(得分:0)

我提出将回调添加到最长的集合中。这样,在处理完所有内容后就会发生回调。

在延迟执行功能中,我这样做:

if (treeCount == maxLeavesTreeIndex) {
    // for last tree pass callback
    workOnTree(trees[treeCount], callback);
}

因此,最后处理的集合不会获得回调,而是最大的集合。

请参阅here

您如何看待这个解决方案?

如果你有更好的想法,请提交答案。