私は類似したユースケースを持っていたので、私は、これはあなたを助けるべきだと思います。
次のメソッドは、Promisesを返す場合と返さない場合がある)メソッドの配列をとり、順番に実行します。処理が進む前に各遅延が完了するまで待機します。デフォルトの動作は失敗時に停止することです。 2番目の引数は、呼び出しが失敗したかどうかにかかわらず処理を続行します。
ハンドラシグネチャが(配列< コンテキスト>)機能(配列<オブジェクト{拒否|解決:引数}>)が失敗/行わコンテキスト各resolveWith/rejectWith呼び出しのコンテキストである、または問題の遅延との引数は解決/拒否で渡された引数セットです。
(function ($) {
"use strict";
var copy = function (a) {
return Array.prototype.slice.call(a);
};
/**
Handle a sequence of methods, stopping on failure by default
@param Array<Function> chain List of methods to execute. Non-deferred return values will be treated as successful deferreds.
@param Boolean continueOnFailure Continue executing even if one of the returned deferreds fails.
@returns Deferred
*/
$.sequence = function (chain, continueOnFailure) {
var handleStep, handleResult,
steps = copy(chain),
def = new $.Deferred(),
defs = [],
results = [];
handleStep = function() {
if (!steps.length) {
def.resolveWith(defs, [ results ]);
return;
}
var step = steps.shift(),
result = step();
handleResult(
$.when(result).always(function() {
defs.push(this);
}).done(function() {
results.push({ resolved: copy(arguments) });
}).fail(function() {
results.push({ rejected: copy(arguments) });
})
);
};
handleResult = continueOnFailure ?
function (result) {
result.always(function() {
handleStep();
});
} :
function (result) {
result.done(handleStep)
.fail(function() {
def.rejectWith(defs, [ results ]);
});
};
handleStep();
return def.promise();
};
}(this.jQuery));
使用の簡単な例:http://jsfiddle.net/rG9rA/
function func1() {
var dfd = $.Deferred();
setTimeout(function() {
dfd.resolve('Password');
}, 1000);
return dfd.promise();
}
function func2(message) {
var dfd = $.Deferred();
setTimeout(function() {
if (message == 'Password') {
dfd.resolve('Hello World');
}
}, 1000);
return dfd.promise();
}
$.sequence([func1, func2, function() { alert('done'); }]);
人々は、このような簡潔な方法で物事を説明するとき、私は大好きです。理解しやすくするために – tim
注: '.pipe'はjQuery 1.8([docs](http://api.jquery.com/deferred.pipe/))で非推奨になっているので' .then'を使用してください。 – nhylated