Fungsi throttling, sederhananya, membuat fungsi tidak dapat dipanggil terus menerus dalam interval waktu yang sangat singkat. Hanya ketika fungsi terakhir telah dieksekusi setelah interval waktu yang ditentukan oleh Anda dapat panggilan berikutnya ke fungsi dilakukan.
Prinsip fungsi pelambatan cukup sederhana. Saya kira semua orang memikirkannya, itu adalah timernya. Ketika saya memicu waktu, pertama -tama setTimout untuk menunda acara untuk sementara waktu sebelum dieksekusi. Jika acara dipicu lagi dalam interval waktu ini, maka kami menghapus timer asli dan kemudian menyelesaikan timer baru untuk menunda eksekusi untuk sementara waktu, itu saja.
Dalam skenario berikut, skenario berikut sering melakukan perilaku berat seperti operasi DOM dan pemuatan sumber daya, menyebabkan UI berhenti atau bahkan browser crash.
1. Ubah Ubah Ubah dan Gulir Acara Jendela Objek
2. Acara Mousemove Selama Menyeret
3. Mousedown dan Keydown Events in Shooting Games
4. Acara Keyup yang secara otomatis diselesaikan dengan input teks
Bahkan, untuk ubah ukuran jendela, persyaratan sebenarnya adalah berhenti mengubah ukuran n milidetik dan melakukan pemrosesan selanjutnya; Sementara sebagian besar peristiwa lain memerlukan pemrosesan selanjutnya pada frekuensi tertentu. Ada dua solusi untuk dua kebutuhan ini, Debounce dan Throttle.
Throttle dan Debounce adalah dua solusi untuk menyelesaikan masalah ketidakcocokan permintaan dan respons. Perbedaan antara keduanya terletak pada memilih strategi yang berbeda.
Jalankan fungsi pada interval seperti throttle.
Jika acara dipicu lagi dalam interval debounce T, timer akan ditetapkan kembali sampai waktu berhenti lebih besar dari atau sama dengan t.
1. Implementasi fungsi throttle sederhana
function throttle (fn, threshhold, scope) {threshhold || (threshhold = 250); var terakhir, timer; return function () {var context = scope || ini; var sekarang = +tanggal baru (), args = argumen; if (last && now - last + threshhold <0) {// pegang saja clearTimeout (deferTimer); timer = setTimeout (function () {last = now; fn.Apply (konteks, args);}, threshhold); } else {last = sekarang; fn.Apply (konteks, args); }};}Metode panggilan
$ ('body'). on ('mousemove', throttle (function (event) {console.log ('centang');}, 1000));2. Implementasi sederhana fungsi debounce
fungsi debounce (fn, delay) {var timer = null; return function () {var context = this, args = argumen; ClearTimeout (timer); timer = setTimeout (function () {fn.Apply (konteks, args);}, tunda); };}Metode panggilan
$ ('input.username'). Keypress (debounce (function (event) {// Lakukan permintaan AJAX}, 250));3. Implementasi Kemasan Sederhana
/** * throttle * @param fn, tunggu, debounce */var throttle = function (fn, tunggu, debounce) {var timer = null, // timer t_last = null, // set kali terakhir, // context args, // parameter diff; // perbedaan waktu pengembalian funciton () {var Curr = + new date (); var context = this, args = argumen; ClearTimeout (timer); if (debounce) {// Jika debounce timer = setTimeout (function () {fn.Apply (konteks, args);}, tunggu); } else {// jika throttle if (! t_last) t_last = Curr; if (Curr - t_last> = tunggu) {fn.Apply (konteks, tunggu); konteks = tunggu = null; }}}}/** * debounce * @param fn, tunggu */var debounce = fungsi (fn, tunggu) {return throttle (fn, tunggu, true);}Ringkasan: Kedua metode ini cocok untuk beberapa peristiwa yang akan dipicu berulang kali, seperti: mousemove, keydown, keyup, keypress, gulir, dll.
Jika Anda hanya mengikat peristiwa asli dan tidak mengendalikannya, browser akan tergagap dan pengalaman pengguna akan buruk. Untuk meningkatkan kinerja JS, disarankan untuk menggunakan fungsi pelambatan atau fungsi untuk mengontrol saat menggunakan peristiwa di atas dan serupa.
4. Analisis Kode Sumber Terkait dengan Underscore V1.7.0
1. _.Throttle Function
_.throttle = function (func, tunggu, opsi) {var context, args, hasil; var timeout = null; // timer var sebelumnya = 0; // Waktu terakhir dipicu if (! Options) option = {}; var kemudian = function () {sebelumnya = options.leading === false? 0: _.now (); timeout = null; result = func.Amply (konteks, args); if (! timeout) context = args = null; }; return function () {var now = _.now (); // apakah akan mengeksekusi if (! Sebelumnya && options.leading === false) sebelumnya = sekarang; // Berikut ini adalah konsep yang tersisa: berapa lama waktu yang tersisa untuk mengeksekusi peristiwa var tetap = tunggu - (sekarang - sebelumnya); konteks = ini; args = argumen; // Tersisa <= 0 Mengingat bahwa acara tersebut diceritakan kembali setelah acara dihentikan atau // ketika menunggu persis berbeda, acara tersebut akan dipicu segera // tetap> tunggu tidak memperhitungkan skenario yang sesuai // karena sekarang sebelumnya yang masih positif dan tidak ada 0, yang tersisa, yang akan selalu lebih kecil dari menunggu, dan tidak ada yang lebih besar dari tunggu dan tidak ada yang aman, dan tidak ada yang aman, dan tidak ada yang akan lebih kecil, dan tidak ada yang akan lebih kecil, dan tidak ada yang lebih kecil, dan tidak ada yang lebih kecil dari itu, dan tidak ada yang lebih kecil dari itu, dan tidak ada yang lebih kecil, dan tidak ada yang lebih kecil dari itu, dan tidak ada yang lebih kecil dari itu, dan tidak ada yang lebih kecil dari itu, dan tidak ada yang lebih kecil dari itu, dan tidak ada yang lebih kecil dari itu, dan tidak ada yang lebih kecil dari itu, dan tidak ada yang lebih kecil dari itu, dan tidak ada yang lebih kecil dari itu juga > tunggu) {if (timeout) {clearTimeout (timeout); timeout = null; } sebelumnya = sekarang; result = func.Amply (konteks, args); if (! timeout) context = args = null; // apakah akan melacak} else if (! Timeout && options.trailing! == false) {timeout = setTimeout (nanti, tersisa); } hasil pengembalian; };};Seperti yang dapat dilihat dari hal di atas, garis bawah telah mempertimbangkan lebih banyak situasi: opsi.
Pertama kali dieksekusi, standarnya benar, yang berarti bahwa pertama kali akan dieksekusi. Opsi eksekusi pertama kali. Trailing dinonaktifkan: terakhir kali dieksekusi, standarnya benar, yang berarti bahwa terakhir kali akan dieksekusi. Terakhir kali disahkan {trailing: false} berarti bahwa terakhir kali tidak dieksekusi. Yang disebut pertama kali adalah apakah acara tersebut dieksekusi terlebih dahulu. Ketika acara baru saja dimulai, apakah acara tersebut harus dipicu terlebih dahulu. Jika Anda mau, sebelumnya = 0, dan tetap negatif, yang disebut terakhir kali apakah fungsi dieksekusi, segera dipanggil setelah acara selesai. Metode ini dipicu terakhir kali. Jika Anda ingin mengeksekusi, timer ditetapkan, yaitu, itu harus dieksekusi sekali setelah acara selesai. Remianing> tunggu berarti waktu klien telah dimodifikasi.
2. _.Debounce fungsi
_.debounce = function (func, tunggu, langsung) {// default langsung adalah false var timeout, args, konteks, cap waktu, hasil; var kemudian = function () {// Ketika fungsi dikembalikan oleh _.debounce disebut beberapa kali selama interval waktu yang ditentukan dengan menunggu, nilai stempel waktu akan terus diperbarui, menghasilkan yang terakhir <tunggu && terakhir> = 0 selalu benar, sehingga terus -menerus memulai newer untuk keterlambatan eksekusi fungsi var terakhir = _.nownow () - - dengan konstan baru untuk memulai tunda untuk penundaan funct funct var = _.now () - - sehingga terus -menerus memulai newer untuk penundaan eksekusi fungsi var terakhir = _.nownow () - timest; if (terakhir <tunggu && last> = 0) {timeout = setTimeOut (nanti, tunggu - terakhir); } else {timeout = null; if (! segera) {result = func.Apply (konteks, args); if (! timeout) context = args = null; }}}; return function () {context = this; args = argumen; timestamp = _.now (); // Ketika metode ini disebut pertama kali dan segera setelah interval waktu yang ditentukan oleh Wait, timer mulai memanggil fungsi fungsi jika (! Timeout) timeout = setTimeout (nanti, tunggu); if (callnow) {result = func.Apply (konteks, args); konteks = args = null; } hasil pengembalian; };};Saya pikir hal yang luar biasa tentang implementasi _.debounce adalah memulai timer secara rekursif alih -alih menyesuaikan eksekusi penundaan fungsi fungsi dengan menelepon ClearTimeout.
Di atas adalah fungsi optimasi kinerja JavaScript yang melambung dan fungsi debounce yang diperkenalkan oleh editor kepada Anda. Saya harap ini akan membantu Anda. Jika Anda memiliki pertanyaan, silakan tinggalkan saya pesan dan editor akan membalas Anda tepat waktu. Terima kasih banyak atas dukungan Anda ke situs web Wulin.com!