0

私は現在、AJAXの非同期動作を回避しようとしています。問題は、私がすべて待たなければならない不特定の量のAJAX呼び出しがあることです。私はjQueryを使用して、成功ハンドラーを含む最後のajax呼び出しが終了するとすぐに手動で解決される遅延オブジェクトを作成しています。正常に動作しますが、then()関数が実行される前に、すべてが発生した関数が終了した(およびその関数内で宣言されたすべての変数をクリーンアップした)ようです。この問題を解決するには、必要な可変ユーザーをグローバルに宣言する必要があります。

私が宣言した場合

$().click(function() {
     /* inside here */ 
     var users = [];
});

その後、それは動作しません。コンソールは、varusersが宣言されていないと述べています。(コード例を参照)。

この問題を解決するためのクリーンなアプローチは何ですか?必要なすべての変数をグローバルに宣言することは、私にはあまり良くないようです。

私のコード例でjsfiddleへのリンク

4

2 に答える 2

1

すべての関数がアクセスできるスコープで変数を宣言する必要があります。getGroupMembers関数はグローバルスコープにあるため、users変数はグローバルスコープである必要があります。readyorスコープに移動するとclick、変数をローカルとして宣言できます。

ただし、リクエストの結果を引数として に渡す方がはるかに簡単ですresolve

$(document).ready(function() {
    $('#message_send').click(function() {
        var deferred = getGroupMembers({
            page: 1,
            per_page: 100
        });
        deferred.then(function(users) {
            console.log(users);
        });
    });
});

function getGroupMembers(querydata) {
    var users = [];
    var deferredObject = new $.Deferred();
    …
    // some asynchronous tasks, callbacking either
        deferredObject.resolve(users);
    // or
        deferredObject.reject();
    …
    return deferredObject.promise();
}

シンタックス シュガーについては、Ajax Deferredのpipeメソッドをそのまま使用することもできます。


再帰的なパイプ方式:

function getGroupMembers(querydata) {
    return $.ajax({
        url: "/echo/json/",
        dataType: "json",
        data: querydata,
        cache: false
    }).pipe(function(data) {
        var user = data.response.UserActions,
            users = [];
        for (var u = 0; u < user.length; u++) {
            users.push(user[u].user.id);
        }
        if (querydata.page < data.meta.total_pages) {
            querydata.page++;
            return getGroupMembers(querydata).pipe(function(nextusers) {
                return users.concat(nextusers);
            });
        } else {
            return users;
        }
    });
}
于 2012-08-22T00:45:55.517 に答える
0

クロージャでこれを回避できますが、async.js を見ることをお勧めします。

ajax 呼び出しの最後の応答を次の関数に渡したい場合

https://github.com/caolan/async#series

次々と ajax を実行している場合、おそらくより良い選択はウォーターフォールです

https://github.com/caolan/async#waterfall

ウォーターフォールはシリーズと同じですが、関数のいずれかが失敗した場合/シリーズが失敗した場合は停止します

複数の ajax 呼び出しを実行し、それらがすべて終了するまで待機する場合

https://github.com/caolan/async#parallel

于 2012-08-18T18:11:16.423 に答える