1. Apakah objek tertunda?
Dalam proses membangunkan tapak web, kami sering menghadapi operasi JavaScript tertentu yang mengambil masa yang lama. Antaranya, terdapat kedua-dua operasi tak segerak (seperti data pelayan membaca ajax) dan operasi segerak (seperti melintasi tatasusunan yang besar), dan hasilnya tidak tersedia serta-merta.
Pendekatan biasa adalah untuk menentukan fungsi panggil balik untuk mereka. Iaitu, nyatakan terlebih dahulu fungsi mana yang harus dipanggil sebaik sahaja ia selesai dijalankan.
Walau bagaimanapun, jQuery sangat lemah apabila ia berkaitan dengan fungsi panggil balik. Untuk mengubahnya, pasukan pembangunan jQuery mereka bentuk objek tertunda.
Ringkasnya, objek tertunda ialah penyelesaian fungsi panggil balik jQuery. Dalam bahasa Inggeris, defer bermaksud "penangguhan", jadi maksud objek tertunda ialah "menangguhkan" pelaksanaan sehingga satu titik tertentu pada masa hadapan.
Ia menyelesaikan masalah cara mengendalikan operasi yang memakan masa, menyediakan kawalan yang lebih baik ke atas operasi tersebut dan antara muka pengaturcaraan bersatu. Fungsi utamanya boleh diringkaskan kepada empat perkara. Di bawah ini kita akan mempelajari langkah demi langkah melalui kod sampel.
2. Kaedah penulisan rantai operasi ajax
Pertama, mari kita semak cara tradisional menulis operasi ajax jQuery:
Dalam kod di atas, $.ajax() menerima parameter objek Objek ini mengandungi dua kaedah: kaedah kejayaan menentukan fungsi panggil balik selepas operasi berjaya, dan kaedah ralat menentukan fungsi panggil balik selepas operasi gagal.
Selepas operasi $.ajax() selesai, jika anda menggunakan versi jQuery yang lebih rendah daripada 1.5.0, objek XHR akan dikembalikan dan anda tidak boleh melakukan operasi rantaian jika versi lebih tinggi daripada 1.5.0 , objek Tertunda yang dikembalikan boleh dirantai.
Kini, cara penulisan baharu ialah ini:
Seperti yang anda lihat, done() adalah bersamaan dengan kaedah kejayaan, dan fail() adalah bersamaan dengan kaedah ralat. Selepas menggunakan kaedah penulisan berantai, kebolehbacaan kod bertambah baik.
3. Tentukan berbilang fungsi panggil balik untuk operasi yang sama
Salah satu faedah hebat objek tertunda ialah ia membolehkan anda menambah berbilang fungsi panggil balik secara bebas.
Mengambil kod di atas sebagai contoh, jika selepas operasi ajax berjaya, sebagai tambahan kepada fungsi panggil balik asal, saya juga ingin menjalankan fungsi panggil balik yang lain, apakah yang perlu saya lakukan?
Ia sangat mudah, cuma tambahkannya pada penghujungnya.
Anda boleh menambah seberapa banyak fungsi panggil balik yang anda suka, dan ia akan dilaksanakan mengikut susunan ia ditambahkan.
4. Tentukan fungsi panggil balik untuk berbilang operasi
Satu lagi faedah hebat objek tertunda ialah ia membolehkan anda menentukan fungsi panggil balik untuk berbilang acara, yang tidak boleh dilakukan dengan penulisan tradisional.
Sila lihat kod berikut, yang menggunakan kaedah baharu $.when():
Maksud kod ini ialah melakukan dua operasi pertama $.ajax("test1.html") dan $.ajax("test2.html"). Jika kedua-duanya berjaya, jalankan panggilan balik yang ditentukan oleh fungsi done(). ; jika salah satu gagal atau kedua-duanya gagal, fungsi panggil balik yang ditentukan oleh fail() dilaksanakan.
5 Antara muka fungsi panggil balik untuk operasi biasa (Bahagian 1)
Kelebihan terbesar objek tertunda ialah ia memanjangkan set antara muka fungsi panggil balik ini daripada operasi ajax kepada semua operasi. Dalam erti kata lain, sebarang operasi - sama ada operasi ajax atau operasi tempatan, sama ada operasi tak segerak atau operasi segerak - boleh menggunakan pelbagai kaedah objek tertunda untuk menentukan fungsi panggil balik.
Mari kita lihat contoh khusus. Katakan terdapat operasi yang memakan masa menunggu:
Sememangnya, anda akan berfikir bahawa anda boleh menggunakan $.when():
Walau bagaimanapun, jika ditulis seperti ini, kaedah done() akan dilaksanakan serta-merta dan tidak akan berfungsi sebagai fungsi panggil balik. Sebabnya ialah parameter $.when() hanya boleh menjadi objek tertunda, jadi wait() mesti ditulis semula:
[kod]
var dtd = $.Deferred(); // Cipta objek tertunda baharu
var tunggu = fungsi(dtd){
var tasks = function(){
alert("Pelaksanaan selesai!");
dtd.resolve(); // Tukar status pelaksanaan objek tertunda
};
setTimeout(tugas,5000);
kembalikan dtd;
};
Sekarang, fungsi wait() mengembalikan objek tertunda, jadi operasi rantai boleh ditambah.
Selepas fungsi wait() dijalankan, fungsi panggil balik yang ditentukan oleh kaedah done() akan dijalankan secara automatik.
6. kaedah deferred.resolve() dan deferred.reject()
Jika anda melihat dengan teliti, anda akan mendapati terdapat tempat lain dalam fungsi wait() di atas yang tidak saya jelaskan. Itulah yang dtd.resolve() lakukan?
Untuk menjelaskan isu ini, kami perlu memperkenalkan konsep baharu "keadaan pelaksanaan". jQuery menetapkan bahawa objek tertunda mempunyai tiga keadaan pelaksanaan - belum selesai, selesai dan gagal. Jika status pelaksanaan "selesai" (diselesaikan), objek tertunda segera memanggil fungsi panggil balik yang ditentukan oleh kaedah done() jika status pelaksanaan "gagal", fungsi panggil balik yang ditentukan oleh kaedah fail() dipanggil; jika status pelaksanaan "tidak berjaya" Selesai", teruskan menunggu, atau panggil fungsi panggil balik yang ditentukan oleh kaedah progress() (ditambah dalam versi jQuery 1.7).
Semasa operasi ajax di bahagian sebelumnya, objek tertunda akan menukar status pelaksanaannya secara automatik berdasarkan hasil pulangan bagaimanapun, dalam fungsi tunggu(), status pelaksanaan ini mesti ditentukan secara manual oleh pengaturcara. Maksud dtd.resolve() ialah menukar status pelaksanaan objek dtd daripada "belum selesai" kepada "selesai", sekali gus mencetuskan kaedah done().
Begitu juga, terdapat juga kaedah deferred.reject(), yang menukar status pelaksanaan objek dtd daripada "tidak lengkap" kepada "gagal", dengan itu mencetuskan kaedah fail().
7. kaedah deferred.promise()
Masih ada masalah dengan cara penulisan di atas. Iaitu, dtd ialah objek global, jadi status pelaksanaannya boleh diubah dari luar.
Sila lihat kod di bawah:
Saya menambah baris dtd.resolve() pada penghujung kod, yang menukar status pelaksanaan objek dtd, sekali gus menyebabkan kaedah done() dilaksanakan serta-merta, dan "Haha, berjaya!" kotak gesaan muncul, dsb. 5 Selepas beberapa saat, kotak gesaan "Pelaksanaan Selesai!" akan muncul.
Untuk mengelakkan situasi ini, jQuery menyediakan kaedah deferred.promise(). Fungsinya adalah untuk mengembalikan objek tertunda lain pada objek tertunda asal yang terakhir hanya membuka kaedah yang tidak berkaitan dengan menukar status pelaksanaan (seperti kaedah done() dan kaedah fail()), dan menyekat kaedah yang berkaitan dengan menukar. status pelaksanaan ( Seperti kaedah resolve() dan kaedah reject()), supaya status pelaksanaan tidak boleh diubah.
Sila lihat kod di bawah:
Walau bagaimanapun, cara yang lebih baik untuk menulisnya adalah seperti yang ditunjukkan oleh allenm, untuk menukar objek dtd menjadi objek dalaman fungsi wait().
8 antara muka fungsi panggil balik untuk operasi biasa (tengah)
Cara lain untuk menghalang keadaan pelaksanaan daripada diubah secara luaran ialah menggunakan fungsi pembina $.Deferred() bagi objek tertunda.
Pada masa ini, fungsi tunggu kekal tidak berubah, kami terus menghantarnya ke $.Deferred():
jQuery menetapkan bahawa $.Deferred() boleh menerima nama fungsi (nota, ia adalah nama fungsi) sebagai parameter, dan objek tertunda yang dijana oleh $.Deferred() akan digunakan sebagai parameter lalai fungsi ini .
9 Antara muka fungsi panggil balik untuk operasi biasa (Bahagian 2)
Selain daripada dua kaedah di atas, kami juga boleh menggunakan antara muka tertunda terus pada objek tunggu.
10. Ringkasan: Kaedah objek tertunda
Kami telah bercakap tentang pelbagai kaedah objek tertunda. Berikut adalah ringkasan:
(1) $.Deferred() menjana objek tertunda.
(2) deferred.done() menentukan fungsi panggil balik apabila operasi berjaya
(3) deferred.fail() menentukan fungsi panggil balik apabila operasi gagal
(4) Apabila deferred.promise() tidak mempunyai parameter, ia mengembalikan objek tertunda baharu dan status berjalan objek tidak boleh ditukar apabila ia menerima parameter, ia berfungsi untuk menggunakan antara muka tertunda pada objek parameter .
(5) deferred.resolve() Menukar status berjalan objek tertunda secara manual kepada "Selesai", sekali gus mencetuskan kaedah done() serta-merta.
(6) deferred.reject() Kaedah ini betul-betul bertentangan dengan deferred.resolve() Selepas dipanggil, status berjalan bagi objek tertunda akan ditukar kepada "gagal", sekali gus mencetuskan kaedah fail(). serta merta.
(7) $.when() menentukan fungsi panggil balik untuk berbilang operasi.
Selain kaedah ini, objek tertunda juga mempunyai dua kaedah penting, yang tidak diliputi dalam tutorial di atas.
(8)ditunda.kemudian()
Kadangkala untuk menyelamatkan masalah, done() dan fail() boleh ditulis bersama Ini ialah kaedah then().
Jika then() mempunyai dua parameter, maka parameter pertama ialah fungsi panggil balik kaedah done() dan parameter kedua ialah kaedah panggil balik bagi kaedah fail(). Jika then() hanya mempunyai satu parameter, ia adalah bersamaan dengan done().
(9) tertunda.selalu()
Kaedah ini juga digunakan untuk menentukan fungsi panggil balik Fungsinya ialah tidak kira sama ada deferred.resolve() atau deferred.reject() dipanggil, ia akan sentiasa dilaksanakan pada akhirnya.