Rumah >hujung hadapan web >tutorial js >Penjelasan terperinci tentang fungsi panggil balik javascript_Pengetahuan asas

Penjelasan terperinci tentang fungsi panggil balik javascript_Pengetahuan asas

WBOY
WBOYasal
2016-05-16 16:31:411522semak imbas

Takrif fungsi panggil balik

Fungsi panggil balik ialah fungsi yang dipanggil melalui penuding fungsi. Jika anda menghantar penuding fungsi (alamat) sebagai parameter kepada fungsi lain, dan apabila penuding ini digunakan untuk memanggil fungsi yang ditunjuknya, kami katakan ia adalah fungsi panggil balik. Fungsi panggil balik tidak dipanggil secara langsung oleh pelaksana fungsi, tetapi dipanggil oleh pihak lain apabila peristiwa atau keadaan tertentu berlaku untuk bertindak balas kepada peristiwa atau keadaan.

Dalam JavaScript, takrifan khusus bagi fungsi panggil balik ialah: fungsi A dihantar sebagai parameter (rujukan fungsi) kepada fungsi B yang lain, dan fungsi B ini melaksanakan fungsi A. Katakan saja fungsi A dipanggil fungsi panggil balik. Jika tiada nama (ungkapan fungsi), ia dipanggil fungsi panggil balik tanpa nama. Oleh itu, panggilan balik tidak semestinya digunakan untuk penggunaan tak segerak sering digunakan dalam senario segerak (menyekat) umum, seperti memerlukan pelaksanaan fungsi panggil balik selepas menjalankan operasi tertentu.

Contoh
Contoh penggunaan panggilan balik dalam penyegerakan (blocking), tujuannya adalah untuk melaksanakan func2 selepas pelaksanaan kod func1 selesai.

Salin kod Kod adalah seperti berikut:

var func1=function(panggilan balik){
//buat sesuatu.
(panggil balik && jenis(panggil balik) === "fungsi") && panggil balik();
}
func1(func2);
var func2=function(){
}

Acara penggunaan fungsi panggil balik
Pemuatan sumber: laksanakan panggilan balik selepas memuatkan fail js secara dinamik, laksanakan panggilan balik selepas memuatkan iframe, panggilan balik operasi ajax, laksanakan panggilan balik selepas pemuatan imej selesai, AJAX, dsb.

Acara DOM dan acara Node.js adalah berdasarkan mekanisme panggil balik (Panggil balik Node.js mungkin menghadapi masalah dengan sarang panggil balik berbilang lapisan).
Masa kelewatan setTimeout ialah 0. Penggodaman ini sering digunakan Fungsi yang dipanggil oleh settimeout sebenarnya adalah penjelmaan panggilan balik

Panggilan berantai: Apabila dirantai, adalah mudah untuk melaksanakan panggilan berantai dalam kaedah penyerah (setter) (atau dalam kaedah yang tidak mengembalikan nilai itu sendiri), tetapi getter (pengambil) agak sukar untuk dilaksanakan panggilan berantai, kerana anda memerlukan penilai untuk mengembalikan data yang anda perlukan dan bukannya penuding ini. Jika anda ingin melaksanakan kaedah berantai, anda boleh menggunakan fungsi panggil balik untuk melaksanakannya

Panggilan fungsi setTimeout dan setInterval mendapat nilai pulangannya. Oleh kerana kedua-dua fungsi adalah tidak segerak, iaitu, urutan panggilan mereka agak bebas daripada proses utama program, tidak ada cara untuk menunggu nilai pulangan mereka dalam badan, dan program tidak akan berhenti dan menunggu apabila mereka berada. dibuka. Jika tidak, makna setTimeout dan setInterval akan hilang, jadi tidak bermakna untuk menggunakan return, dan panggilan balik hanya boleh digunakan. Maksud panggilan balik adalah untuk memberitahu fungsi ejen hasil pelaksanaan pemasa untuk pemprosesan tepat pada masanya.

Fungsi juga merupakan objek

Jika anda ingin memahami fungsi panggil balik, anda mesti memahami dengan jelas peraturan fungsi tersebut. Dalam JavaScript, fungsi adalah pelik, tetapi ia sememangnya objek. Lebih tepatnya, fungsi ialah objek Fungsi yang dibuat menggunakan pembina Function(). Objek Fungsi mengandungi rentetan yang mengandungi kod JavaScript fungsi tersebut. Jika anda datang dari C atau Java, ini mungkin kelihatan pelik. Bagaimanakah kod itu boleh menjadi rentetan? Tetapi dengan javascript, ini adalah perkara biasa. Perbezaan antara data dan kod adalah kabur.

Salin kod Kod adalah seperti berikut:

//Anda boleh mencipta fungsi seperti ini
var fn = Fungsi baharu("arg1", "arg2", "return arg1 * arg2;");
fn(2, 3); //6

Satu kelebihan melakukan ini ialah anda boleh menghantar kod ke fungsi lain, atau anda boleh menghantar pembolehubah atau objek biasa (kerana kod secara literal hanyalah objek).

Menghantar fungsi sebagai panggil balik

Mudah untuk lulus fungsi sebagai parameter.

Salin kod Kod adalah seperti berikut:

fungsi fn(arg1, arg2, panggil balik){
var num = Math.ceil(Math.random() * (arg1 - arg2) arg2);
​ panggil balik(nombor);//Pindahkan hasil
}

fn(10, 20, fungsi(bilangan){
console.log("Panggil balik! Num: " num); });//Hasilnya ialah nombor rawak antara 10 dan 20

Mungkin ini kelihatan menyusahkan atau agak bodoh Mengapa anda tidak mengembalikan hasilnya seperti biasa? Tetapi apabila anda perlu menggunakan fungsi panggil balik, anda mungkin tidak fikir begitu!

Jauhi jalan

Fungsi tradisional memasukkan data dalam bentuk parameter dan menggunakan pernyataan pulangan untuk mengembalikan nilai. Secara teorinya, terdapat pernyataan pulangan pada penghujung fungsi, iaitu secara struktur: titik input dan titik output. Ini lebih mudah difahami Fungsi pada dasarnya adalah pemetaan proses pelaksanaan antara input dan output.

Walau bagaimanapun, apabila proses pelaksanaan fungsi sangat panjang, adakah anda memilih untuk menunggu fungsi selesai pemprosesan atau menggunakan fungsi panggil balik untuk pemprosesan tak segerak? Dalam kes ini, menjadi penting untuk menggunakan fungsi panggil balik, sebagai contoh: permintaan AJAX. Jika anda menggunakan fungsi panggil balik untuk pemprosesan, kod boleh terus melaksanakan tugas lain tanpa menunggu dengan sia-sia. Dalam pembangunan sebenar, panggilan tak segerak sering digunakan dalam JavaScript, malah ia amat disyorkan di sini!

Di bawah ialah contoh yang lebih komprehensif menggunakan AJAX untuk memuatkan fail XML dan menggunakan fungsi call() untuk memanggil fungsi panggil balik dalam konteks objek yang diminta.

Salin kod Kod adalah seperti berikut:

fungsi fn(url, panggil balik){
var httpRequest; //Buat XHR
httpRequest = window.XMLHttpRequest ? XMLHttpRequest() baharu : 
   window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP"    ): undefined;//Pengesanan fungsional untuk IE
 
httpRequest.onreadystatechange = function(){
Jika(httpRequest.readystate === 4
. ​​​​​ callback.call(httpRequest.responseXML); }
};
httpRequest.open("GET", url);
httpRequest.send();
}

fn("text.xml", function(){   //Fungsi panggilan console.log(this); //Keluaran selepas pernyataan ini

});

console.log("ini akan dijalankan sebelum panggilan balik di atas."); //Pernyataan ini dikeluarkan dahulu


Kami meminta pemprosesan tak segerak, yang bermaksud apabila kami memulakan permintaan, kami memberitahu mereka untuk memanggil fungsi kami apabila ia selesai. Dalam situasi sebenar, pengendali acara onreadystatechange juga mesti mempertimbangkan situasi kegagalan permintaan Di sini kami menganggap bahawa fail xml wujud dan boleh berjaya dimuatkan oleh penyemak imbas. Dalam contoh ini, fungsi tak segerak diperuntukkan kepada acara onreadystatechange dan oleh itu tidak akan dilaksanakan serta-merta.

Akhirnya, pernyataan console.log kedua dilaksanakan terlebih dahulu kerana fungsi panggil balik tidak dilaksanakan sehingga permintaan selesai.

Contoh di atas tidak mudah difahami, jadi lihat contoh berikut:

fungsi foo(){
var a = 10;
Kembalikan fungsi(){
        a *= 2;
         kembali a;                                     };  
}
var f = foo();
f(); //kembali 20.
f(); //kembali 40.



Apabila fungsi dipanggil secara luaran, pembolehubah a masih boleh diakses. Ini semua kerana skop dalam JavaScript adalah leksikal. Fungsi dijalankan dalam skop di mana ia ditakrifkan (skop di dalam foo dalam contoh di atas), bukan skop di mana fungsi itu dijalankan. Selagi f ditakrifkan dalam foo, ia boleh mengakses semua pembolehubah yang ditakrifkan dalam foo, walaupun pelaksanaan foo telah tamat. Kerana skopnya akan disimpan, tetapi hanya fungsi yang dikembalikan boleh mengakses skop yang disimpan ini. Mengembalikan fungsi tanpa nama bersarang ialah cara paling biasa untuk membuat penutupan.
Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn