2011-09-26

[jquery] 複数の $.get が全部終わるまで待つには

jQuery を使って、リクエストを並列に送った後、すべてのレスポンスが出そろうまで待って処理をする、ということをやりたい場合は、jQuery.when() を使います。この関数を使うと、引数に与えた複数の Deferred オブジェクトから、新しく Deferred オブジェクトを作ってくれます。

jQuery 1.5 (2011/1/31リリース) 以降で利用可能です。

jQuery.get() の返り値 jqXHR は jQuery 1.5 以降では都合の良いことに Deferred になっているので、jQuery.when() にこれをそのまま渡せばよいです。

以下の例において、arg_a, arg_b は、もともとの Deferred の done の引数リストになっているので、jQuery.get() の、success(data, textStatus, jqXHR) の data を得るためには arg_a[0] 等とする必要があることに注意します。

$.when($.get('/path_a'), $.get('/path_b')).done(function(arg_a, arg_b) {
    var a_data = arg_a[0],
        b_data = arg_b[0];

    console.log([a_data, b_data]);
});

さらに、制限時間以内にレスポンスがそろわなかった場合に失敗とするには、以下のようにすれば良いです。

var timerDeferred = $.Deferred();

setTimeout(timerDeferred.reject, 1000);

$.when($.get('/path_a'), $.get('/path_b'), timerDeferred)
    .done(function(arg_a, arg_b) {
        var a_data = arg_a[0],
            b_data = arg_b[0];

        console.log([a_data, b_data]);
    })
    .fail(function() {
        console.log('fail');
    });