Saya ingin membuat tiga panggilan ajax dalam acara klik. Setiap panggilan ajax melakukan operasi yang berbeda dan mengembalikan data yang diperlukan untuk panggilan balik akhir. Panggilan itu sendiri tidak tergantung satu sama lain, mereka semua bisa pergi pada saat yang sama, namun saya ingin memiliki panggilan balik terakhir ketika ketiganya selesai.
$('#button').click(function() {
fun1();
fun2();
fun3();
//now do something else when the requests have done their 'success' callbacks.
});
var fun1= (function() {
$.ajax({/*code*/});
});
var fun2 = (function() {
$.ajax({/*code*/});
});
var fun3 = (function() {
$.ajax({/*code*/});
});
Jawaban:
Ini adalah objek callback yang saya tulis di mana Anda bisa mengatur satu callback untuk diaktifkan setelah semuanya selesai atau membiarkan masing-masing memiliki callback mereka sendiri dan memecat mereka semua setelah semuanya selesai:
MEMPERHATIKAN
Karena jQuery 1.5+ Anda dapat menggunakan metode tangguhan seperti dijelaskan dalam jawaban lain:
Contoh ditangguhkan di sini
untuk jQuery <1.5 berikut ini akan berfungsi atau jika Anda perlu panggilan ajax Anda dipecat pada waktu yang tidak diketahui seperti yang ditunjukkan di sini dengan dua tombol: dipecat setelah kedua tombol diklik
[pemakaian]
untuk panggilan balik tunggal setelah selesai: Contoh Kerja
masing-masing memiliki panggilan balik sendiri ketika semuanya selesai: Contoh Kerja
[Kode]
sumber
setCallback
untuk menambahkan lebih banyak ke antrian. Meskipun sekarang saya berpikir tentang itu ... Saya harus menyebutnyaaddCallback
atau semacamnya ... dan tidak hanya mengatur karena itu menambah antriansingleCallback
variabel pada baris ke-2 tidak perlu? Atau apakah saya melewatkan sesuatu?Sepertinya Anda sudah mendapatkan beberapa jawaban untuk ini, namun saya pikir ada sesuatu yang layak disebutkan di sini yang akan sangat menyederhanakan kode Anda. jQuery memperkenalkan
$.when
di v1.5. Sepertinya:Tidak melihatnya disebutkan di sini, semoga membantu.
sumber
Tidak melihat kebutuhan untuk objek yang jelek sendiri. Sederhana memiliki variabel yang merupakan bilangan bulat. Saat Anda memulai permintaan, tambahkan nomornya. Ketika seseorang selesai, kurangi itu. Saat nol, tidak ada permintaan yang sedang berlangsung, jadi Anda selesai.
sumber
if (!--inProgress)
. Versi yang benar analog denganinProgress = inProgress - 1; if (inProgress == 0) { /* do stuff */ }
. Bentuk ringkas menggabungkan operator penurunan awalan (--
) dan operator negasi (!
) untuk mengevaluasi ke "true" (dan karenanya mengeksekusiif
blok), jikainProgress
hasil decrementing dalaminProgress == 0
, dan mengevaluasi ke "false" (dan karena itu tidak melakukan apa-apa) sebaliknya.Perlu dicatat bahwa karena
$.when
mengharapkan semua permintaan ajax sebagai argumen berurutan (bukan array), Anda biasanya akan melihat$.when
digunakan dengan.apply()
seperti:Ini karena
$.when
menerima argumen seperti iniDan tidak seperti ini:
sumber
all
metode atau yang serupa, tapi saya suka konsep peta. Bagus.Saya suka ide hvgotcodes. Saran saya adalah menambahkan incrementer generik yang membandingkan jumlah lengkap dengan jumlah yang dibutuhkan dan kemudian menjalankan panggilan balik akhir. Ini dapat dibangun ke dalam callback akhir.
[Diedit untuk mencerminkan pembaruan nama.]
sumber
EDIT - mungkin opsi terbaik adalah membuat titik akhir layanan yang melakukan semua yang diminta oleh ketiga permintaan. Dengan begitu Anda hanya perlu melakukan satu permintaan, dan semua data adalah di mana Anda membutuhkannya sebagai respons. Jika Anda menemukan 3 permintaan yang sama berulang kali, Anda mungkin ingin menempuh rute ini. Seringkali merupakan keputusan desain yang baik untuk mengatur layanan fasad pada server yang menggabungkan tindakan server kecil yang biasa digunakan bersama-sama. Hanya sebuah ide.
salah satu cara untuk melakukannya adalah dengan membuat objek 'sinkronisasi' di handler klik Anda sebelum panggilan ajax. Sesuatu seperti
Sinkronisasi akan terikat pada ruang lingkup panggilan sukses secara otomatis (penutupan). Di penangan sukses, Anda menambah hitungan, dan jika itu 3 Anda dapat memanggil fungsi lainnya.
Atau, Anda bisa melakukan sesuatu seperti
ketika setiap keberhasilan dieksekusi, itu akan mengubah nilai dalam sinkronisasi menjadi true. Anda harus memeriksa sinkronisasi untuk memastikan ketiganya benar sebelum melanjutkan.
Catat kasus di mana salah satu xhrs Anda tidak mengembalikan kesuksesan - Anda harus memperhitungkannya.
Namun pilihan lain adalah selalu memanggil fungsi terakhir dalam penangan sukses Anda, dan minta akses opsi sinkronisasi untuk menentukan apakah benar-benar melakukan sesuatu. Anda perlu memastikan bahwa sinkronisasi berada dalam lingkup fungsi itu.
sumber
Saya mengajukan pertanyaan yang sama beberapa waktu lalu dan mendapat beberapa jawaban yang baik di sini: Cara terbaik untuk menambahkan 'panggilan balik' setelah serangkaian panggilan XHR yang tidak sinkron
sumber
Saya mendapat beberapa petunjuk bagus dari jawaban di halaman ini. Saya mengadaptasinya sedikit untuk saya gunakan dan berpikir saya bisa membagikannya.
Ada beberapa batasan di sini, tetapi untuk kasus saya itu ok. Saya juga menemukan bahwa untuk hal-hal yang lebih maju ada juga plugin AOP (untuk jQuery) yang mungkin berguna: http://code.google.com/p/jquery-aop/
sumber
Saya menemukan masalah ini hari ini, dan ini adalah upaya naif saya sebelum menonton jawaban yang diterima.
sumber
Ini bukan jquery (dan tampaknya jquery memiliki solusi yang bisa diterapkan) tetapi hanya sebagai pilihan lain ....
Saya memiliki masalah serupa yang banyak bekerja dengan layanan web SharePoint - Anda sering perlu menarik data dari berbagai sumber untuk menghasilkan input untuk satu proses.
Untuk mengatasinya saya menanamkan fungsionalitas semacam ini ke perpustakaan abstraksi AJAX saya. Anda dapat dengan mudah mendefinisikan permintaan yang akan memicu satu set penangan saat selesai. Namun setiap permintaan dapat didefinisikan dengan beberapa panggilan http. Berikut komponennya (dan dokumentasi terperinci):
DPAJAX di DepressedPress.com
Contoh sederhana ini membuat satu permintaan dengan tiga panggilan dan kemudian meneruskan informasi itu, dalam urutan panggilan, ke penangan tunggal:
Perhatikan bahwa tidak seperti banyak solusi lain (termasuk, saya percaya solusi "kapan" dalam jquery) asalkan metode ini tidak memaksa threading tunggal dari panggilan yang dibuat - masing-masing masih akan berjalan secepat (atau selambat) jika lingkungan memungkinkan tetapi penangan tunggal hanya akan dipanggil ketika semua sudah selesai. Ini juga mendukung pengaturan nilai batas waktu dan coba lagi jika layanan Anda sedikit flakey.
Saya telah menemukannya sangat berguna (dan sangat sederhana untuk dipahami dari perspektif kode). Tidak ada lagi rantai, tidak ada lagi menghitung panggilan dan menyimpan output. Rencanakan itu dan lupakan itu".
sumber
Ok, ini sudah tua tapi tolong izinkan saya berkontribusi solusi saya :)
Ini juga berfungsi dengan fungsi yang memiliki panggilan balik. Anda mengatur syncCount dan Anda memanggil fungsi sync (...) di callback setiap tindakan.
sumber
Saya menemukan cara yang lebih mudah untuk melakukannya tanpa perlu metode tambahan yang mengatur antrian.
JS
PHP (ajax1.php)
PHP (ajax2.php)
sumber
Secara default, semua permintaan dikirim secara tidak sinkron (mis. Ini disetel ke true secara default). Jika Anda membutuhkan permintaan sinkron, atur opsi ini ke
false
. Permintaan dandataType: "jsonp"
permintaan lintas-domain tidak mendukung operasi sinkron. Perhatikan bahwa permintaan sinkron dapat sementara mengunci browser, menonaktifkan tindakan apa pun saat permintaan aktif. Pada jQuery 1.8 , penggunaanasync: false
dengan jqXHR ($.Deferred
) sudah usang; Anda harus menggunakan opsi keberhasilan / kesalahan / panggilan balik lengkap alih-alih metode yang sesuai dari objek jqXHR sepertijqXHR.done()
atau yang sudah usangjqXHR.success()
.sumber
Maaf, saya tidak bisa menjelaskan apa yang saya maksud. Saya orang Korea yang tidak bisa berbicara sepatah kata pun dalam bahasa Inggris. tapi saya pikir Anda dapat dengan mudah memahaminya.
sumber