Saya memiliki kode yang terlihat seperti ini di javascript:
forloop {
//async call, returns an array to its callback
}
Setelah SEMUA panggilan asinkron selesai, saya ingin menghitung min di atas semua array.
Bagaimana saya bisa menunggu semuanya?
Satu-satunya ide saya saat ini adalah memiliki larik boolean yang disebut selesai, dan menyetel selesai [i] menjadi true dalam fungsi panggilan balik ke-i, lalu mengatakan while (tidak semua selesai) {}
edit: Saya kira satu solusi yang mungkin, tetapi jelek, adalah mengedit array done di setiap callback, lalu memanggil metode jika semua selesai lainnya disetel dari setiap callback, sehingga callback terakhir yang diselesaikan akan memanggil metode berkelanjutan.
Terima kasih sebelumnya.
javascript
asynchronous
codersarepeople
sumber
sumber
while (not all are done) { }
tidak akan berhasil. Saat Anda sibuk menunggu, tidak ada panggilan balik Anda yang dapat berjalan.Jawaban:
Anda belum terlalu spesifik dengan kode Anda, jadi saya akan membuat skenario. Katakanlah Anda memiliki 10 panggilan ajax dan Anda ingin mengumpulkan hasil dari 10 panggilan ajax tersebut dan kemudian ketika semuanya telah selesai Anda ingin melakukan sesuatu. Anda dapat melakukannya seperti ini dengan mengumpulkan data dalam array dan melacak kapan yang terakhir selesai:
Penghitung Manual
Catatan: penanganan error penting di sini (tidak ditampilkan karena ini khusus untuk cara Anda melakukan panggilan ajax). Anda akan ingin memikirkan bagaimana Anda akan menangani kasus ketika satu panggilan ajax tidak pernah selesai, baik dengan kesalahan atau macet untuk waktu yang lama atau waktu habis setelah waktu yang lama.
jQuery Janji
Menambah jawaban saya pada tahun 2014. Akhir-akhir ini,
$.ajax()
promise sering digunakan untuk menyelesaikan masalah jenis ini karena jQuery sudah mengembalikan sebuah promise dan$.when()
akan memberi tahu Anda saat sekelompok promise telah diselesaikan dan akan mengumpulkan hasil yang dikembalikan untuk Anda:Janji Standar ES6
Seperti yang ditentukan dalam jawaban kba : jika Anda memiliki lingkungan dengan promise bawaan (browser modern atau node.js atau menggunakan babeljs transpile atau menggunakan promise polyfill), Anda dapat menggunakan promise yang ditentukan ES6. Lihat tabel ini untuk dukungan browser. Janji didukung di hampir semua browser saat ini, kecuali IE.
Jika
doAjax()
mengembalikan sebuah promise, Anda dapat melakukan ini:Jika Anda perlu membuat operasi asinkron non-promise menjadi operasi yang mengembalikan promise, Anda bisa "menjanjikan" seperti ini:
Dan, kemudian gunakan pola di atas:
Janji Bluebird
Jika Anda menggunakan pustaka yang lebih kaya fitur seperti pustaka janji Bluebird , maka itu memiliki beberapa fungsi tambahan bawaan untuk membuatnya lebih mudah:
sumber
doAjax()
janji yang mengembalikan sebagai salah satu opsi. Sama sepertifetch()
.Memeriksa dari 2015: Kami sekarang memiliki janji asli di browser terbaru (Edge 12, Firefox 40, Chrome 43, Safari 8, Opera 32 dan browser Android 4.4.4 dan iOS Safari 8.4, tetapi tidak Internet Explorer, Opera Mini, dan versi yang lebih lama Android).
Jika kita ingin melakukan 10 tindakan asinkron dan mendapatkan pemberitahuan ketika semuanya sudah selesai, kita dapat menggunakan yang asli
Promise.all
, tanpa pustaka eksternal:sumber
Promises.all()
seharusnyaPromise.all()
.Promise.all()
yang tidak menyertakan versi IE terkini.Anda bisa menggunakan objek Deferred jQuery bersama dengan metode when .
sumber
jQuery
yang biasanya berarti OP tidak menginginkan jawaban jQuery.Anda dapat menirunya seperti ini:
maka setiap panggilan asinkron melakukan ini:
sementara di setiap panggilan asinkron kembali di akhir metode Anda menambahkan baris ini:
Dengan kata lain, Anda meniru fungsi hitung-mundur-latch.
sumber
Ini cara yang paling rapi menurut saya.
Promise.all
FetchAPI
(untuk beberapa alasan Array.map tidak berfungsi di dalam. lalu fungsi untuk saya. Tetapi Anda dapat menggunakan .forEach dan [] .concat () atau yang serupa)
sumber
return responses.map(response => { return response.json(); })
, ataureturn responses.map(response => response.json())
.Gunakan pustaka aliran kontrol seperti
after
sumber