JavaScriptでAPIからデータ取得・処理する際、ネスト地獄で複雑なコードになりがち。 かと言って、AngularやReactなどのフレームワークを使うと勉強コスト、スパゲティー設計など本末転倒な結果になりやすい。
フレームワークの最大のデメリットは、
中で何が行われているか?ソースを解読しないとわからない
と言うことで、こみいった実装をせずシンプルに実装してみる。
(1) APIリクエストの配列設定 (2) Ajax処理の抽象化 (3) 並列処理の抽象化 (4) コールバック処理の考慮
$(document).on('click', '.action-api', function() {
//API設定(抽象化する必要あり)
var requests = [
{
url: 'https://xxxx/api/user',
params: {'user_id': 394},
callback: callbackUser
},
{
url: 'https://xxxx/api/order',
params: {'user_id': 394, 'item_id': 31},
callback: callbackApplication
},
];
//並列処理実行
parallelAjax(requests, doneCallback);
//各APIリクエストのコールバック
function callbackUser(results) {
console.log(results);
}
function callbackApplication(results) {
console.log(results);
}
//並列処理完了後のコールバック
function doneCallback(results) {
console.log(results);
}
});
var requestAjax = function(values){
var $ajax = $.ajax(values);
var defer = new $.Deferred();
$ajax.done(function(data, status, $ajax){
defer.resolveWith(this, arguments);
});
$ajax.fail(function(data, status, $ajax){
defer.resolveWith(this, arguments);
});
return $.extend({}, $ajax, defer.promise());
};
function parallelAjax(requests, callback) {
var results = [];
$.each (requests, function(index, value) {
var $ajax = requestAjax({url: value.url, data: value.params}).done(function(res, status) {
if (value.callback) {
value.callback(res);
}
});
results.push($ajax);
});
$.when.apply(null, results).done(function(){
if (callback) callback(results);
});
$.when.apply(null, results).fail(function(){
});
}
並列処理は後々ループで実行ため、オブジェクト配列で設定しておく。 差し当たり以下の項目で設定 ・URL ・URLパラメータ ・API処理後のコールバック (その他、POST/GETやデータ型なども設定できると良い?)
var requests = [
{
url: 'https://xxxx/api/user',
params: {'user_id': 394},
callback: callbackUser
},
{
url: 'https://xxxx/api/application',
params: {'user_id': 394},
callback: callbackApplication
},
];
こうすることで、callbackを別モデル、ファイルなどに分離して記述できるかと。 実用レベルだと、APIリクエスト設定も動的に抽象化が必要ですが。。。
並列処理をする際「jQuery.Deferred」を利用 ざっとした流れは、 (1) Deferredオブジェクトを作成 (2) Ajaxリクエスト (3) Ajax処理後返り値を Deferred.resolveWith() でコールバック
詳しくは、 ・「爆速でわかるjQuery.Deferred超入門」 ・「結局jQuery.Deferredの何が嬉しいのか分からない、という人向けの小話」を参照
var requestAjax = function(values) {
var $ajax = $.ajax(values);
var defer = new $.Deferred();
$ajax.done(function(data, status, $ajax) {
defer.resolveWith(this, arguments);
});
$ajax.fail(function(data, status, $ajax) {
defer.resolveWith(this, arguments);
});
return $.extend({}, $ajax, defer.promise());
};
(1) 配列化したリクエストをループで処理 (2) Ajax実行 (3) APIリクエストで設定したコールバックを実行 (3) $.whenで並列処理完了後の処理
function parallelAjax(requests, callback) {
var results = [];
$.each (requests, function(index, value) {
var $ajax = requestAjax({url: value.url, data: value.params}).done(function(res, status) {
if (value.callback) {
value.callback(res);
}
});
results.push($ajax);
});
$.when.apply(null, results).done(function(){
if (callback) callback(results);
});
$.when.apply(null, results).fail(function(){
});
}