Tôi đã có một trường hợp sử dụng tương tự, vì vậy tôi nghĩ rằng điều này sẽ giúp bạn ra ngoài.
Phương pháp sau sẽ lấy một loạt các phương thức (có thể hoặc không trả lại lời hứa) và thực thi chúng theo thứ tự, đợi cho đến khi mỗi lần trì hoãn hoàn tất trước khi tiếp tục. Hành vi mặc định là dừng lại trên thất bại; đối số thứ hai cho phép bạn tiến hành cuộc gọi không thành công hay không.
thực hiện/không chữ ký handler là (Mảng < bối cảnh>) Chức năng (Mảng < Object {từ chối | giải quyết: luận}>), nơi bối cảnh là bối cảnh của mỗi resolveWith cuộc gọi/rejectWith, hoặc trì hoãn được đề cập và đối số là bộ đối số được chuyển trong độ phân giải/từ chối.
(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));
Một ví dụ đơn giản sử dụng: 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'); }]);
tôi yêu khi người ta giải thích điều theo cách ngắn gọn như vậy. dễ hiểu hơn và theo dõi – tim
Lưu ý: Sử dụng '.then' vì' .pipe' đã không được chấp nhận trong jQuery 1.8 ([docs] (http://api.jquery.com/deferred.pipe/)) – nhylated