0

次の問題があります。

受け取ったパラメーターに応じて、配列を処理して何かを行う関数があるとします。次のようなものです:

 var arr = [];

 function processArr(p1, p2, ....){};

p1、p2 などはサーバーから受信されるため、次のようになります。

processArr(<?php echo $p1; ?>, <?php echo $p2; ?>, ...)
processArr(<?php echo $p1; ?>, <?php echo $p2; ?>, ...)
processArr(<?php echo $p1; ?>, <?php echo $p2; ?>, ...)
processArr(<?php echo $p1; ?>, <?php echo $p2; ?>, ...)
processArr(<?php echo $p1; ?>, <?php echo $p2; ?>, ...)

実際にはphpですが、実際には問題ではありません。

問題: js は呼び出しを次々に処理するのではなく、同時に (正確に同時にではなく、十分に近い) 処理します。したがって、最初の呼び出しで要素を配列に追加し (次に他の処理)、2 番目の呼び出しで要素を削除しようとすると、要素はまだ追加されていないため、削除時に存在しません。

最初の呼び出しが終了するのを待つために 2 番目の呼び出しを行うにはどうすればよいですか?

追加機能:

    function processSaved(act, params)
    {
        if (act == 1)
        {
            var newUser = params;
            if (user.id == newUser.id)
                user = clone(newUser);
            activeElementIndex = i;
            // Go to the next level from the active element level
            var newLevel = newUser.level;

            // Set current level
            currentLevel = Math.max(currentLevel, newLevel);

            // Create new object and push it to elements array
            var obj = newUser;
            elements.push(obj);
            activeElementIndex = newUser.parent;
            // Add element to order list
            if (orderElements.length + 1 > newLevel)
            {
                var added = 0;
                for (var i = 0; i < orderElements[newLevel - 1].el.length; i++)
                {
                    if (elements[activeElementIndex].column < elements[elements[orderElements[newLevel - 1].el[i]].parent].column)
                    {
                        orderElements[newLevel - 1].el.splice(i, 0, elements.length - 1);
                        added = 1;
                        break;
                    }
                }

                if (added == 0)
                    orderElements[newLevel - 1].el.push(elements.length - 1);
            }
            else
            {
                var tmp = new Array();
                tmp.push(elements.length - 1);
                var obj = {"el": tmp};
                orderElements[newLevel - 1] = obj;
            }

            flagCreate = 1;
            actions.push(newUser);
            // Call the rearange function
            rearangeElementsWithoutRedraw();
        }
        else if (act == 0)
        {
            activeElementIndex = params.index;
            deleteNode();
        }

        return true;                                                
    }

最初の呼び出しは act = 1 で行われます。2 番目の呼び出しは act = 0 で行われます。2 番目の呼び出しにタイムアウトを追加すると、たとえば 0.5 秒ですべて正常に動作します。そうでない場合、要素が存在しないため、削除時にエラーが発生します。これは、最初の呼び出しが完了する前に 2 番目の呼び出しが行われたことを示しています。

4

2 に答える 2

2

JS は関数を並行して呼び出しません。関数processArrは順次実行されます。

これは明らかに、関数内で AJAX リクエストなどを単純に開始しないことを前提としています。次の関数を実行すると、リクエストが完了するまで (同期されるまで) 待機しません。

于 2012-05-15T10:27:34.433 に答える
0

問題が見つかりました。私が使用していたライブラリ (raphaeljs) によって行われた非同期呼び出しがありました。時間を無駄にして申し訳ありません:)。

于 2012-05-15T11:31:51.777 に答える