0

私はこれを一人で理解することはできず、あなたの助けが必要です. phonegap アプリでネストされたバックボーン オブジェクトを操作していて、それらをすべて保存したいと考えています。保存中に読み込みアニメーションを表示したい。すべてが保存されたら、次のページ/ステップに進みたいと思います。これは既に達成しましたが、保存ループがすべての UI 更新をブロックしているため、アニメーションが機能しません。(私はajax経由ではなく、localStorageに保存しています。)したがって、各アイテムの保存の間にタイムアウトを挿入して、保存を遅くしようとしました。現在、保存は遅れていますが、インターフェイスはすべてが実際に保存される前に次のページに進みます。コールバックが正しく設定されていないようです。

きれいにネストされたコールバックのパターンを知っていますか?

私の問題を説明するフィドルをまとめました。

アラートが正しい順序で作成されるように、修正を手伝ってもらえますか。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 モデルを使用したほうがよいのではないでしょうか?

UI イベントを実行して更新を取得するためだけに setTimout() が必要です。それほど長くする必要はありません。0ms または 1ms (最適化の場合のみ) で十分です。

私がすることは、リストの 1 つから 1 つのリーフ項目を取得して処理し、さらに作業がある場合は 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 に答える