AJAX処理を順番に実行する
やりたいこと
複数のAJAX処理を一つずつ順番に、前の処理が終わるのを待って実行したい。
環境
jQuery 1.8 以降
やり方
jQueryのDeferredオブジェクトを利用してAJAX実行Queueを作成する。途中でエラーが発生した際にそのまま続行するQueueと以降の処理をキャンセルするQueue、2通り作ってみた。
エラー後も続行するQueue
// AJAX実行Queue var ajaxQueue = function () { var previous = new $.Deferred().resolve(); return function (fn) { // then()の第1と第2引数に同じ関数を渡す return previous = previous.then(fn, fn); }; }(); // キューが空なので即実行される ajaxQueue(function () { return $.get('/first'); }); // 1つ目の処理が終わったら実行される ajaxQueue(function() { return $.get('/second'); });
エラー後はキャンセルするQueue
この場合、一度エラーが発生すると以降常にキャンセルされ続けてしまうため、再び処理を開始するための初期化関数も用意した。
// AJAX実行Queue var ajaxQueue = function () { var previous = new $.Deferred().resolve(); return { put: function (fn) { // then()の第1引数のみ渡す return previous = previous.then(fn); }, init: function () { // Deferredオブジェクトの初期化 previous = new $.Deferred().resolve(); } }; }(); // キューが空なので即実行される ajaxQueue.put(function () { return $.get('/first'); }); // 1つ目の処理でエラーが発生していなければ実行される ajaxQueue.put(function() { return $.get('/second'); }); // 初期化 ajaxQueue.init();
補足
AJAX処理に.done()
や.fail()
が登録されている場合、それらの実行まで完了してから次の処理が開始される。
おまけ
前の処理が終わっていないときは次の処理を阻止したい、という場合。
var ajaxQueue = function () { var previous = new $.Deferred().resolve(); return function (fn) { if (previous.state() == 'pending') { alert('通信中です。しばらくお待ち下さい。'); return; } return previous = previous.then(fn, fn); }; }();