Alternatif yang lebih bersih dari saran @Ivo adalah Asynchronous Method Queue , dengan asumsi Anda hanya perlu membuat satu panggilan async untuk koleksi.
(Lihat posting ini oleh Dustin Diaz untuk penjelasan lebih detail)
function Queue() {
this._methods = [];
this._response = null;
this._flushed = false;
}
(function(Q){
Q.add = function (fn) {
if (this._flushed) fn(this._response);
else this._methods.push(fn);
}
Q.flush = function (response) {
if (this._flushed) return;
this._response = response;
while (this._methods[0]) {
this._methods.shift()(response);
}
this._flushed = true;
}
})(Queue.prototype);
Anda cukup membuat instance baru Queue, menambahkan callback yang Anda butuhkan, lalu membersihkan antrean dengan respons asinkron.
var queue = new Queue();
queue.add(function(results){
for (var result in results) {
}
});
someFunction(param1, param2, function(results) {
queue.flush(results);
}
Manfaat tambahan dari pola ini adalah Anda dapat menambahkan beberapa fungsi ke antrean, bukan hanya satu.
Jika Anda memiliki objek yang berisi fungsi iterator, Anda dapat menambahkan dukungan untuk antrian ini di belakang layar dan menulis kode yang terlihat sinkron, tetapi tidak:
MyClass.each(function(result){ ... })
cukup tulis eachuntuk meletakkan fungsi anonim ke dalam antrean alih-alih langsung mengeksekusinya, lalu hapus antrean saat panggilan asinkron Anda selesai. Ini adalah pola desain yang sangat sederhana dan kuat.
PS Jika Anda menggunakan jQuery, Anda sudah memiliki antrian metode async yang Anda inginkan yang disebut jQuery.Deferred .
( /* ... */ )terlihat seperti monster dan aku ketakutan sekarang :(