ここで見栄えの良い解決策を見つけました: How do I chain a sequence of deferred functions in jQuery 1.8.x?
そして、これは同様のアプローチの私自身の実装です。やや醜いですが、おそらく機能しています。返された promise オブジェクトの «progress update» として各メソッドの結果をブロードキャストします。
$.chain = function() {
var defer = $.Deferred();
var funcs = arguments;
var left = funcs.length;
function next(lastResult) {
if(left == 0) {
defer.resolve();
return;
}
var func = funcs[funcs.length - left]; // current func
var prom = func(lastResult).promise(); // for promise will return itself,
// for jquery ojbect will return promise.
// these handlers will be launched in order we specify them
prom.always(function() {
left--;
}).done(function(ret) {
defer.notify({
idx: funcs.length-left,
left: left,
result: ret,
success: true,
});
}).fail(function(ret) {
defer.notify({
idx: funcs.length-left,
left: left,
result: ret,
success: false,
});
}).always(function(ret) {
next(ret);
});
}
next();
return defer.promise();
};
状況に応じてどのように使用しますか?美しくないかもしれませんが、うまくいくはずです:
function first() {
return ajax(...);
}
var id;
funciton second() {
return ajax(id, ...);
}
function third() {
return ajax(id, ...);
}
$.chain(first, second, third).progress(function(p) {
if(p.func == first)
id = p.result.identifier;
}).then(function() {
alert('everything is done');
});
または、その id 変数を関数から割り当てることもできfirst
ます。
または、前の関数の結果のみが必要な場合は、次のアプローチを使用できます。
function first() {
return ajax(...);
}
function second(first_ret) {
return ajax(first_ret.id, ...);
}
function third(second_ret) {
return ajax(second_ret.something, ...);
}