Ich hatte einen ähnlichen Anwendungsfall, also denke ich, dies sollten Ihnen helfen.
Die folgende Methode benötigt ein Array von Methoden (die Promises zurückgeben können oder nicht) und sie nacheinander ausführen, wobei gewartet wird, bis jede Deferred abgeschlossen ist, bevor Sie fortfahren. Das Standardverhalten besteht darin, bei einem Fehler zu stoppen. Mit dem zweiten Argument können Sie fortfahren, ob der Anruf fehlschlägt oder nicht.
getan/Handler Signaturen (Array < Kontext>) Funktion (Array < Objekt {abgelehnt | aufgelöst: Argumente}>) fehlschlagen, wo Kontext ist der Kontext jedes resolveWith/rejectWith Anruf oder das in Frage stehende Deferred, und Argumente ist das Argument, das in der Auflösung/Zurückweisung übergeben wurde.
(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));
Ein einfaches Beispiel für die Verwendung: 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'); }]);
ich liebe, wenn die Menschen die Dinge in so prägnanter Form zu erklären. einfacher zu verstehen und zu folgen – tim
Hinweis: Verwenden Sie ". Then", da '.pipe' in jQuery 1.8 veraltet ist ([docs] (http://api.jquery.com/deferfer.pipe/)) – nhylated