0

私は次のような状況にあります。サーバーからファイルAをロードしたいのですが、サーバーは(Aの内容に応じて)ファイルA1、A2、A3、...をロードしようとします。各ファイルA[1-n]は他のファイルをロードし、これを続行できます。はい、それには終わりがあります。

残念ながら、私は同期を使用する必要があることに気付きました$.ajax requests。そうしないと、最初の$ .ajax呼び出し(ファイルAのロードが終了したとき)が残りのファイルを経由せずに戻るだけです。私の関数は次のようになります:

loadFile = function (path, file, scope)
{
    $.ajax ({
        url: url,
        type: 'GET',
        dataType: 'text',
        success: function (responseData)
        {
            var lines = responseData.split("\n");
            for (var j = 0; j < lines.length; j++)
            {
                if (lines[j].charAt(0) === 'F')
                    loadFile (arguments);
            }
        }
    });
}

私の最初の質問は、なぜ「async:false」を上記のオプションに追加できないのかということ$.ajaxSetup({async: false});です。そうしないと機能しないため、代わりに使用する必要があります。

私の2番目の質問は、これがこのジョブを再帰的に実行するために使用する正しいパターンです。

私の3番目の質問は、プロセス全体がいつ完了したかをどうやって知ることができるかということです。私はこれを理解することはできません。

4

1 に答える 1

1

async: falseすべての悪の根源です。タブ全体をブロックしており、場合によっては(古いIEのように)ブラウザ全体をブロックします。使用しないでください。

今あなたの問題の解決策。あなたはこのようなことをすることができます:

// note new argument "callback"
var loadFiles = function(path, file, scope, callback) {
    var req = $.ajax({
        // some settings
        success: function(res) {
            // some processing
            for (var j = 0; j < lines.length; j++) {
                loadFiles.requests.push(
                    // the same callback
                    loadFiles(path2, file2, scope2, callback)
                );
            }

            // set this request to complete
            req.completed = true;

            // check if all requests are done
            for (var i = 0; i < loadFiles.requests.length; i++) {
                if (!loadFiles.requests[i].completed) {
                    return;
                }
            }
            // TODO: you could remove completed requests from that array
            // to increase performance

            // if all are done then reset the array and run the callback
            delete loadFiles.requests;
            if (callback) {
                callback();
            }
        }
    });
    if (!loadFiles.requests || !loadFiles.requests.length) {
        loadFiles.requests = [req];
    }
    return req;
};

loadFiles(path, file, scope, function() {
    // this happens after all is done
});

この関数を2回続けて呼び出すと、壊れることに注意してください(これloadFiles.requestsはグローバル関数のプロパティであるため)。これをサポートするには、すべてを外部関数でラップして、その関数を使用する必要があります。

于 2013-03-23T13:08:45.140 に答える