0

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

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

我整理了一个小提琴来说明我的问题

您能帮我修复它,以便它以正确的顺序创建警报: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);
4

3 回答 3

1

如果我了解您要实现的目标,并且我认为我做到了(但我可能错了),那么使用 Queue 模型会更好吗?

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

我要做的是有一个回调函数,它从您的一个列表中获取一个叶子项目,处理它,然后如果还有更多工作要做,则每次使用 setTimeout() 重新安排更多工作。

这样,您的操作将得到串行处理。我认为您不希望它们并行运行,尽管看起来就是这样。所以你的回调也将被序列化。

我知道您已经专门构建了一个人为的示例来尽可能简单地演示该问题,但这使得您很难看到您正在尝试做什么,但我这样说对吗?

于 2013-07-08T13:02:16.500 回答
0

我认为您应该使用 .sort() 方法,并且应该在此方法中添加自己的参数。这些会给你一个想法: 如何使用 jQuery 按字母顺序对列表进行排序? http://james.padolsey.com/javascript/sorting-elements-with-jquery/

于 2013-07-03T20:08:35.903 回答
0

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

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

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

所以不是最后处理的集合得到回调,而是最大的集合。

这里

你觉得这个解决方案怎么样?

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

于 2013-07-03T23:24:36.773 回答