Penjelasan terperinci tentang Panggilan Balik dalam kod sumber jQuery analysis_jquery

WBOY
Lepaskan: 2016-05-16 16:09:47
asal
1293 orang telah melayarinya

Intipati kod menyerlahkan konsep jujukan dan susunan, terutamanya dalam JavaScript - lagipun, JavaScript ialah enjin satu benang.

Javascript mempunyai ciri-ciri pengaturcaraan berfungsi, dan disebabkan enjin satu-benang JavaScript, fungsi kami sentiasa perlu dilaksanakan dengan teratur. Kod yang sangat baik selalunya memotong fungsi ke dalam modul mereka sendiri dan kemudian melaksanakannya dalam keadaan tertentu Memandangkan fungsi ini dilaksanakan dengan teratur, mengapa tidak kita menulis objek pengurusan bersatu untuk membantu kita menguruskan fungsi ini - jadi, Panggilan Balik (fungsi panggil balik. ) dilahirkan.

Apakah Panggilan Balik

Javascript penuh dengan pengaturcaraan berfungsi Contohnya, window.onload yang paling mudah menerima fungsi yang menyedihkan ialah window.onload hanya boleh menerima satu fungsi jika ia ditetapkan secara langsung laksanakan dalam onload, Kemudian kita perlu menulis kod berikut:

Salin kod Kod adalah seperti berikut:

fungsi a(elemen) {
                elem.innerHTML = 'Saya fungsi a, saya mahu menukar struktur HTML Elemen';
        };
         fungsi b(elemen) {
                elem.innerHTML = 'Fungsi saya b, saya mahu menukar gaya Elemen';
}
          window.onload = fungsi () {
               var elem = document.getElementById('test');
a(elem);
              b(elem);
        };

Niat asal fungsi panggil balik adalah untuk membina perkara sedemikian. Ia tidak lagi membenarkan kami menyerakkan fungsi ini, tetapi untuk mengatur fungsi ini dalam cara yang bersatu. Seperti yang anda lihat, kami ingin melakukan dua perkara untuk Elemen dalam window.onload: mula-mula tukar struktur html, dan kemudian tukar gaya html. Kedua-dua fungsi juga beroperasi pada Elemen, dan pelaksanaan akhir kedua-dua fungsi ini dilakukan mengikut urutan. Jadi mengapa kita tidak menulis objek seperti ini untuk menguruskan fungsi ini. Sudah tentu, ini hanyalah makna paling asas bagi fungsi panggil balik Kami memerlukan lebih daripada sekadar objek fungsi panggil balik yang mudah, kami memerlukan fungsi panggil balik yang lebih berkuasa. Nah, ini hanyalah kes penggunaan yang mudah, jadi saya boleh memberitahu anda apa fungsi panggil balik ini boleh lakukan selain melaksanakan fungsi satu demi satu.

Intipati Panggilan Balik adalah untuk mengawal pelaksanaan fungsi yang teratur Javascript ialah enjin satu benang, yang bermaksud bahawa hanya satu kod dalam JavaScript berjalan pada masa yang sama - malah Ajax dan setTimeout. Kedua-dua fungsi ini nampaknya tidak segerak, tetapi ini tidak berlaku Apabila pelayar menjalankan kod javascript, kod ini akan ditolak ke dalam baris gilir dengan teratur Apabila anda menjalankan Ajax, penyemak imbas akan Menolak ke dalam baris gilir penyemak imbas mengambil kod satu demi satu daripada baris gilir kod semasa memproses kod JavaScript - Panggilan Balik, memenuhi enjin satu benang ini.

Sudah tentu, apa yang kita mahukan adalah lebih daripada sekadar objek alat yang begitu ringkas - dalam kod sumber jQuery, Callbacks menyediakan pengurusan asas set fungsi, menyediakan asas untuk Ditunda (baris gilir tak segerak), dan juga menyediakan Queue (baris gilir penyegerakan). Ditunda digunakan untuk melicinkan/meratakan pengaturcaraan piramid (sebilangan besar fungsi panggil balik bersarang, seperti kod dalam Ajax yang perlu dilaksanakan berdasarkan kod pemulangan permintaan dan pemacu Queue jQuery.animate (enjin animasi).

Kemudian mari tulis Panggilan Balik.

Model panggilan balik

Susun:
Memandangkan Panggilan Balik kami mahu menerima satu siri fungsi, kami mesti mempunyai bekas. Kita boleh menggunakan tatasusunan dan menolak setiap fungsi ke dalam tatasusunan Apabila ia perlu dilaksanakan, gelung item tatasusunan untuk dilaksanakan.

Model Kerja:

Panggil Balik ini perlu sangat berkuasa Ia bukan semudah menolak fungsi dan kemudian melaksanakannya.
sekali: Semua fungsi dalam objek Panggilan Balik semasa hanya akan dilaksanakan sekali, dan akan dikeluarkan selepas pelaksanaan Kami boleh menyediakan penyelesaian yang stabil dan berkesan untuk pengguna yang menggunakan objek Panggilan Balik untuk memastikan bahawa fungsi itu hanya akan dilaksanakan sekali dan tidak akan. dilaksanakan semula , yang menstabilkan rangkaian fungsi ini.
auto: model pelaksanaan automatik Ini adalah model yang menarik Beberapa fungsi bergantung pada fungsi lapisan sebelumnya Sebagai contoh, pelaksanaan fungsi b bergantung pada fungsi a. setiap kali ia ditambahkan Apabila fungsi mencapai Panggilan Balik, ia secara automatik melaksanakan fungsi yang ditambahkan pada masa lalu dan menghantar data parameter terakhir yang diberikan kepada fungsi yang lalu Ini menghapuskan keperluan untuk mencetuskan berulang antara fungsi bergantung ini daripada Panggilan Balik model yang menarik.
sekali&auto: Kita boleh menjadikannya lebih berkuasa dan berfungsi dengan model sekali dan auto pada masa yang sama, iaitu: setiap kali fungsi ditambahkan pada Panggilan Balik, fungsi lalu akan dilaksanakan, dan kemudian, fungsi lalu ini akan dikeluarkan, dan fungsi akan terus ditambah pada masa yang akan datang Pada masa itu, fungsi tersebut pada masa lalu tidak akan dilaksanakan lagi kerana model sekali telah mengeluarkannya.

API:

tambah(fungsi) - Tambah satu (atau lebih) fungsi pada objek Panggilan Balik: Sudah tentu, jika anda tidak menambah fungsi dan hanya ingin melihat Panggilan Balik, kami akan membiarkan anda terus menikmati keseronokan anda - kami tidak akan membuang pengecualian kerana itu bukan sesuatu yang kami mahir.
remove(function) - mengalih keluar fungsi dalam Panggilan Balik: Sekarang kita telah menambahkannya, kita juga harus menyediakan rancangan untuk menyesalinya. Kami sangat mudah didekati dan bertolak ansur dengan semua yang dilakukan oleh orang lain pada masa lalu.
has(function) - Menentukan sama ada Panggilan Balik mengandungi fungsi: Oh? Anda tidak pasti sama ada untuk menyertakan fungsi ini, tetapi anda telah menggunakannya sejak awal! Kenapa awak cuai sangat? Tetapi kerana anda bertanya kepada saya, saya masih akan memberitahu anda sama ada Callback mengandungi fungsi ini. Saya tahu anda sangat sibuk dan tidak dapat mengingati dan menentukan segala-galanya.
empty() - Panggilan Balik Kosong: Adakah fungsi ini kehilangan maknanya kepada anda? apa? Anda tidak mahu lagi selepas ia dilaksanakan? Jadi anda harap anda boleh membersihkannya? Nah, demi ingatan, saya masih bertolak ansur dengan permintaan awak.
disable() - Lumpuhkan Panggilan Balik: Untuk mengekalkan kewujudan yang stabil dengan kod orang lain, saya memilih pengorbanan diri - ya, kaedah ini boleh melumpuhkan Panggilan Balik, melumpuhkan sepenuhnya, seolah-olah ia tidak wujud sebelum ini.
disabled() - Menentukan sama ada Panggilan Balik telah dilumpuhkan: Jika anda masih tidak percaya sama ada Panggilan Balik benar-benar mengorbankan diri, kaedah ini boleh memberi anda ketenangan fikiran.
lock(boolean) - Kunci objek Callback ini: anda takut ia tidak stabil, tetapi anda tidak mahu meninggalkannya Lock adalah kaedah yang baik untuk menunjukkan sama ada objek itu perlu dikunci sudah tentu, ia tidak mempunyai parameter Membolehkan anda menentukan sama ada Panggilan Balik dikunci.
fire(data) - Jalankan fungsi dalam Panggilan Balik ini: Bukankah semua yang kita lakukan untuk nasib pelaksanaan pada masa ini? Parameter akan menjadi parameter fungsi ini yang perlu dilaksanakan.
fireWith(context,data) - Laksanakan fungsi dalam Panggilan Balik dan nyatakan konteks. Dalam fire(), Konteks semua fungsi ialah objek Panggilan Balik, dan fireWidth() membolehkan anda mentakrifkan semula konteks fungsi ini untuk dilaksanakan Betapa percumanya pengaturcaraan, Panggilan Balik mempertimbangkan segala-galanya untuk anda.
fired() - Tentukan sama ada Panggilan Balik ini telah dilaksanakan pada masa lalu: Kami percaya bahawa kebanyakan masa anda tidak tahu perkara yang telah anda lakukan pada masa lalu, tetapi kami merekodkan semua yang anda lakukan Jika anda telah melaksanakan objek Panggilan Balik ini masa lalu, maka anda tidak boleh menafikannya, kerana kami tahu sama ada anda telah melaksanakan Panggilan Balik ini pada masa lalu.

Pelaksanaan modul asas

Pelaksanaan mudah:
Mari kita laksanakan Panggilan Balik:

Salin kod Kod adalah seperti berikut:

(fungsi (tetingkap, tidak ditentukan) {
            var Panggilan Balik = fungsi () {
//Lindungi pembolehubah peribadi ini melalui penutupan
                   senarai var = [],//Senarai fungsi panggil balik
Dipecat; // Adakah anda telah melaksanakan
//Kembalikan penutupan objek Callbakcs
                   kembali {
                         tambah: fungsi (fn) {
//Apabila Panggilan Balik dibuang, senarai itu tidak ditentukan
Jika (senarai) {
//Tambah fungsi panggil balik
                                 senarai.push(fn);
//Sokong panggilan balik rantai
                                                                                                                                                                                                                                                   pulangkan ini;                     },
fireWith: fungsi (konteks, data) {
//Cetuskan fungsi panggil balik dan nyatakan konteks
Jika (senarai) {
dipecat = benar;
untuk (var i = 0, len = list.length; i < len; i ) {
//Apabila fungsi dalam Panggilan Balik mengembalikan palsu, hentikan pelaksanaan Panggilan Balik yang seterusnya
Jika (senarai[i].terapkan(konteks, data) === palsu)
rehat;
                                                                                                                                                                                                                                                                                                                                                                                                      pulangkan ini;                     },
Api: fungsi () {
//Pencetuskan fungsi panggil balik
//Panggil fireWith dan nyatakan konteks
Kembalikan this.fireWith(this, arguments);
                    },
                      kosong: fungsi () {
//Kosongkan senarai
                                                                                                                                                                                                                                                            jika (senarai)//Apabila Panggilan Balik ini dibuang, Panggilan Balik seharusnya tidak boleh terus digunakan
senarai = [];
                                                                                         pulangkan ini;                     },
                           lumpuhkan: fungsi () {
//Tinggalkan objek Panggilan Balik ini dan senarai fungsi panggil balik berikutnya tidak akan dilaksanakan lagi
                         senarai = tidak ditentukan;
                                                                                         pulangkan ini;                     },
                       dilumpuhkan: fungsi () {//Kesan sama ada Panggilan Balik ini telah dilumpuhkan
//Tukar kepada boolean dan kembalikan
Kembalikan senarai !;
                    },
                     dicetuskan: function () {//Sama ada panggilan balik ini telah dilaksanakan
                                                                                                                                                                                                                                                                                                                                                                                                          }
                };
            };
//Daftar ke tetingkap
               tetingkap. Panggilan Balik = Panggilan Balik;
         }(tetingkap));



Kemudian mari kita uji Panggilan Balik ini:

Salin kod Kod adalah seperti berikut:

        ujian var = Panggilan Balik baharu();
         test.add(fungsi (nilai) {
                console.log('Fungsi 1, nilai ialah: nilai ');
        });
         test.add(fungsi (nilai) {
console.log('Fungsi 2, nilai ialah:' nilai);
        });
​​​​ test.fire('Ini ialah nilai fungsi 1 dan fungsi 2');
console.log('Semak sama ada fungsi telah dilaksanakan:' test.fired());
         test.disable();//Abaikan Panggilan Balik ini
console.log('Semak sama ada fungsi itu ditinggalkan:' test.disabled());
         test.add(function () {
console.log('Tambah fungsi ketiga, fungsi ini tidak boleh dilaksanakan');
        });
         test.fire();

Buka konsol penyemak imbas dan kami dapat melihat bahawa hasil yang dijalankan adalah normal.

sekali dan pelaksanaan auto(memori)

sekali:
Sekali membenarkan fungsi dalam panggil balik ini berjalan sekali dan kemudian tidak berjalan lagi. Prinsipnya sangat mudah. ​​Dalam kod di atas, kita dapat melihat bahawa terdapat senarai pembolehubah yang mengambil alih senarai fungsi, jadi kita hanya perlu mengosongkan kod yang telah dilaksanakan pada masa lalu. Kami menggunakan pembolehubah global untuk menyimpan model pelaksanaan semasa Jika ia adalah model sekali, batalkan sahaja senarai dalam fireWith():

Salin kod Kod adalah seperti berikut:

(fungsi (tetingkap, tidak ditentukan) {
            var Panggilan Balik = fungsi (sekali) {
//Lindungi pembolehubah peribadi ini melalui penutupan
                   senarai var = [],//Senarai fungsi panggil balik
Dipecat; // Adakah anda telah melaksanakan
//Kembalikan penutupan objek Callbakcs
                   kembali {
//...Tinggalkan beberapa kod
fireWith: fungsi (konteks, data) {
//Cetuskan fungsi panggil balik dan nyatakan konteks
Jika (senarai) {
dipecat = benar;
untuk (var i = 0, len = list.length; i < len; i ) {
//Apabila fungsi dalam Panggilan Balik mengembalikan palsu, hentikan pelaksanaan Panggilan Balik yang seterusnya
Jika (senarai[i].terapkan(konteks, data) === palsu)
rehat;
                                                                                                                                                                                                                                                                                                             //Jika model sekali dikonfigurasikan, pembolehubah global sekali adalah benar dan senarai ditetapkan semula
Jika (sekali) senarai = tidak ditentukan;
                                                                                         pulangkan ini;                  }
//...Tinggalkan beberapa kod
                };
            };
//Daftar ke tetingkap
               tetingkap. Panggilan Balik = Panggilan Balik;
         }(tetingkap));

auto:

Model auto (memori) dinamakan sempena memori dalam jQuery Saya keliru dengan nama ini pada mulanya Selepas melihat penggunaannya dengan teliti, saya memutuskan untuk menukarnya kepada auto - fungsinya ialah "selepas kebakaran pertama. , "tambah() fungsi secara automatik dilaksanakan" boleh digunakan dalam situasi berikut: selepas menambah set fungsi pada Panggilan Balik, dan buat sementara waktu perlu menambah fungsi, kemudian jalankan fungsi yang baru ditambah dengan segera - ia mesti dikatakan bahawa untuk kemudahan penggunaan, Corak ini menjadi agak sukar untuk difahami. Pelaksanaannya adalah untuk menentukan sama ada ia adalah model auto semasa add(). Walau bagaimanapun, kita perlu melaksanakannya secara automatik selepas fire() pertama yang belum dicetuskan() tidak seharusnya dilaksanakan secara automatik Selain itu, selepas setiap pelaksanaan automatik, parameter terakhir yang digunakan perlu dihantar ke fungsi yang dilaksanakan secara automatik ini.

Mungkin anda akan memikirkan kod berikut:

Salin kod Kod adalah seperti berikut:

(fungsi (tetingkap, tidak ditentukan) {
            var Panggilan balik = fungsi (sekali, automatik) {
              senarai var = [],
dipecat,
lastData;//Simpan parameter pelaksanaan terakhir
                   kembali {
                         tambah: fungsi (fn) {
Jika (senarai) {
                                 senarai.push(fn);
​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ //Parameter terakhir yang digunakan diluluskan, dan Konteks hilang di sini
//Untuk mengelakkan konteks daripada hilang di sini, kita juga mungkin perlu mengisytiharkan pembolehubah untuk menyimpan Konteks terakhir digunakan
Jika (auto) ini.fire(lastData);
                                                                                                                                                                                                                                                   pulangkan ini;                     },
fireWith: fungsi (konteks, data) {
Jika (senarai) {
lastData = data;// — Rekod parameter terakhir digunakan
dipecat = benar;
untuk (var i = 0, len = list.length; i < len; i ) {
Jika (senarai[i].terapkan(konteks, data) === palsu)
rehat;
                                                                                                                                                                                                                                                                                                             Jika (sekali) senarai = [];
                                                                                         pulangkan ini;                  }
//Sebahagian daripada kod ditinggalkan
                };
            };
//Daftar ke tetingkap
               tetingkap. Panggilan Balik = Panggilan Balik;
         }(tetingkap));

Tetapi penggunaan yang lebih menarik diguna pakai dalam jQuery Pengarang jQuery juga berbangga dengan penggunaan ini, jadi dia menamakan memori model ini-iaitu, auto pembolehubah di atas bukan sahaja mewakili mod pelaksanaan auto semasa, tetapi juga berfungsi. sebagai Bekas terakhir parameter, yang mewakili kedua-dua auto dan memori. (Kod berikut bukan jQuery dan ditulis berdasarkan idea kod jQuery, bukan kod sumber):

Salin kod Kod adalah seperti berikut:

(fungsi (tetingkap, tidak ditentukan) {
            var Panggilan Balik = fungsi (auto) {
              senarai var = [],
dipecat,
Memori,//Pelakon utama sudah datang, ia adalah ingatan
coreFire = fungsi (data) {
//Kaedah fungsi pencetus sebenar
Jika (senarai) {
                                                                                                                                                                                                                                                                                                                                  Memori = auto && data;//Rakam parameter terakhir Jika ia tidak berada dalam mod auto, parameter ini tidak akan direkodkan
//Jika ia adalah mod auto, maka auto ini tidak akan palsu, ia akan menjadi tatasusunan
dipecat = benar;
untuk (var i = 0, len = list.length; i < len; i ) {
Jika (senarai[i].apply(data[0], data[1]) === palsu)
rehat;
                                                                                                                                                                                                                                                                                                                                 };
                   kembali {
                         tambah: fungsi (fn) {
Jika (senarai) {
//Tambah fungsi panggil balik
                                 senarai.push(fn);
//Mod pelaksanaan automatik, ambil perhatian bahawa jika model auto
//memori diberikan dalam coreFire(), lalainya adalah palsu
Jika (memori) coreFire(auto);
                                                                                                                                                          //Sokong panggilan balik rantai
                                                                                         pulangkan ini;                    },
fireWith: fungsi (konteks, data) {
Jika (sekali) senarai = [];
//Panggil coreFire di sini dan tukar parameter kepada tatasusunan
coreFire([konteks, data]);
                                                                                         pulangkan ini;                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    };
            };
               tetingkap. Panggilan Balik = Panggilan Balik;
         }(tetingkap));


Kami melihat dalam kod pelaksanaan auto sebelumnya bahawa kami kehilangan Konteks jQuery membetulkan pepijat ini pada awal fireWith() - betulkan parameter dalam fireWith(). jQuery mengekstrak logik yang sepatutnya melaksanakan fungsi dalam fireWith(). Kami menamakannya buat sementara waktu sebagai coreFire(). Parameter mewakili parameter yang diluluskan. Kemudian laksanakan coreFire().


Semasa add(), jQuery tidak memberikan nilai kepada auto(memori) pembolehubah, tetapi memilih untuk memberikan nilai kepada auto(memori) dalam coreFire(), dengan itu memastikan ia tidak akan dihidupkan sehingga yang pertama fire() secara automatik.


Seperti yang dinyatakan di atas, parameter yang diterima oleh coreFire() sebenarnya adalah tatasusunan Parameter pertama ialah konteks, dan parameter kedua ialah parameter yang dihantar dari luar. Pada masa yang sama, tetapkan tatasusunan ini kepada auto (memori), supaya takrifan auto pembolehubah (sama ada untuk melaksanakan mod secara automatik) menjadi memori (memori parameter terakhir diluluskan).

Ia benar-benar idea bernas yang membunuh dua burung dengan satu batu, saya mesti menyukainya. Saya mentakrifkan ini sebagai auto kerana ia adalah model yang dilaksanakan secara automatik, dan dengan cara ini, parameter fire() terakhir disimpan Takrif jQuery sebagai ingatan mungkin menjadi keluhan pengarang untuk hasil kerja yang ajaib di sini.


Untuk sekali&auto, ia hanya menggabungkan kedua-dua kod ini Anda hanya perlu menentukan dalam coreFire() bahawa jika ia adalah mod auto, kemudian tetapkan semula senarai kepada tatasusunan baharu, jika tidak tetapkannya kepada tidak ditentukan secara langsung.

Kod sumber

Kod ini ditulis tangan oleh saya yang sepadan dengan jQuery Beberapa fungsi awam jQuery ditulis. Ia bukan serpihan kod, jadi ia boleh dirujuk dan dijalankan secara langsung.

Salin kod Kod adalah seperti berikut:

(fungsi (tetingkap, tidak ditentukan) {
/*
* Objek alat fungsi panggil balik Ambil perhatian bahawa tatasusunan akan dikosongkan selepas objek kerja selesai:
* * Menyediakan set API biasa, tetapi ia mempunyai model kerja berikut -
- *Model pelaksanaan Auto-Automatik: Setiap penambahan fungsi panggil balik ditambah untuk melaksanakan semua fungsi panggil balik secara automatik dalam set fungsi panggil balik sedia ada, dan parameter masa ini dihantar ke semua fungsi panggil balik
*
*/

//Fungsi alat
var isIndexOf = Array.prototype.indexOf, //Es6
        toString = Object.prototype.toString, //Kaedah Cache toString
TosLice = Array.prototype.slice, // Kaedah Caches Slice
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      kembalikan "objek" === jenis dokumen.getElementById ?
               isFunction = fungsi (fn) {
                      //Terdapat masalah dengan pengiktirafan DOM dan BOM di bawah iaitu
                  cuba {
Kembalikan /^s*bfunctionb/.test("" fn);
                        } tangkap (x) {
Kembali palsu
                }
              } :
               isFunction = function (fn) { return toString.call(fn) === '[object Function]';
         })(),
                                                                                                                                                                                                                                                                                                                                                                                         //Parameter pertama mewakili tatasusunan yang akan digelung dan parameter kedua ialah fungsi yang dilaksanakan setiap kali melalui gelung
Jika (arguments.length < 2 || !isFunction(arguments[1])) kembali;
                       //Mengapa hirisan tidak sah? ?
          senarai var = toSlice.call(argumen[0]),
                              fn = hujah[1],
item;
​​​​​​sementara ((item = list.shift())) {//Tiada penentuan panjang secara langsung, percepatkan
// Mengapa menggunakan panggilan di sini, dan Memohon tidak baik?
                               // Selesai - parameter kedua permohonan mestilah objek tatasusunan (tiada pengesahan sama ada seperti tatasusunan boleh dilakukan dan panggilan tidak mempunyai keperluan ini)
                                                                           // apply diterangkan seperti berikut: Jika argArray (parameter kedua) bukan array yang sah.
                           fn.call(tetingkap, item);
            }
},
inArray = function () { //Kesan sama ada tatasusunan mengandungi item dan kembalikan indeks item
                                                                                                                                                                                                                                                                       // Pra-penyusunan
                 return isIndexOf ? Jika (susun)
                          return isIndexOf.call(array, elem, i);
                    pulangan -1;
               } : fungsi (elemen, tatasusunan, i) {
              var len;
                     jika (tatasusunan) {
                    len = array.length;
                    saya = saya? i < 0 ? Math.max(0, len i) : i : 0;
                    untuk (; i < len; i ) {
                        if (i dalam tatasusunan && tatasusunan[i] === elem) {
                            kembalikan i;
                        }
                    }
                }
                kembali -1;
            }
        }();

var Panggilan Balik = fungsi (pilihan) {
          pilihan = toString.call(option) === '[objek Objek]' ? ​​​​ //Gunakan penutupan kerana setiap panggilan balik baharu mempunyai keadaannya sendiri
        var list = [],                                                                                                                                                                                                                                                                                          senarai                 _list = [],        // Jika objek panggil balik ini dikunci, kosongkan senarai dan letakkan senarai asal ke dalam _list
                                                                                                                                                                                                                                                                                              telah dilaksanakan
firingStart, //Indeks fungsi (titik permulaan) dilaksanakan oleh senarai fungsi panggil balik semasa
              panjang tembakan,                                                                                                                                                      // Panjang tatasusunan panggilan balik                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                // Penggunaan pembolehubah ini sangat pelik dan tajam, ia bukan sahaja mengandungi bendera sama ada untuk menentukan pelaksanaan, tetapi juga merekodkan data
//Kereta ini benar-benar gila apabila digunakan dengan sekali: [Buat kali pertama] ia akan dilaksanakan secara automatik selepas melaksanakan tembakan Dengan sekali, ia boleh dilakukan: setelah dilaksanakan, tiada kod akan ditambahkan atau dilaksanakan kemudian, memastikan kestabilan. dan kestabilan satu set data panggil balik Selamat
tindanan = !option.once && [], //Timbunan panggil balik Jika tatasusunan panggil balik sedang dilaksanakan dan fungsi panggil balik baharu ditambah semasa pelaksanaan, maka fungsi panggil balik baharu akan ditolak ke dalam tatasusunan panggil balik
            penembakan = palsu, //Sama ada panggilan balik berfungsi/melaksanakan
//Pencetuskan fungsi panggil balik
api = fungsi (data) {
//Perhatikan bahawa data ini ialah tatasusunan Jika mod auto dikonfigurasikan, auto tidak akan palsu kerana auto akan menjadi tatasusunan
                    auto = option.auto && data; //Di sini, jika konfigurasi memerlukan menghafal parameter terakhir, maka ingat parameter ini (penggunaan yang sangat tajam, ambil data terus)
dipecat = benar;
firingIndex = firingStart || 0;
                firingStart = 0;//Clear firingStart (jika anda tidak mengosongkannya, akan ada masalah dalam pelaksanaan seterusnya)
Firinglength = list.length; // panjang senarai cache, dunia luar boleh mengakses
                  penembakan = benar; // Melaksanakan fungsi panggil balik
untuk (; firingIndex < firingLength; firingIndex ) {
Jika (senarai[firingIndex].apply(data[0], data[1]) === palsu) {
// Perhatikan, jika option.auto (pelaksanaan automatik) dikonfigurasikan, dan terdapat fungsi dalam timbunan (timbunan), maka terdapat bahagian kod dalam kod add() yang akan secara langsung melaksanakan kaedah ini untuk penghakiman automatik
//Kami mahu menyekat kod itu, jadi tetapkan auto kepada palsu
                                  auto = palsu;
                          rehat;
                                     }//Apabila fungsi mengembalikan palsu, tamatkan pelaksanaan baris gilir berikutnya
                }
                firing = false; // Status bendera telah dilaksanakan fungsi panggil balik [fungsi dalam tindanan (timbunan) belum lagi dilaksanakan]
//Jika timbunan ini tidak dikonfigurasikan sekali, ia mestilah [], jadi mesti ada
//Fungsi utama di sini ialah jika sekali tidak dikonfigurasikan, kod berikut akan dipintas Jika sekali dikonfigurasikan, data akan dikosongkan selepas melaksanakan kod
                      jika (timbunan) {
Jika (stack.length) // Mula-mula memintas kod keadaan penyenaraian di bawah, dan kemudian tentukan sama ada terdapat tindanan
Fire (stack.shift ()); // Keluarkan ia daripada kepala tindanan dan ulang kaedah FIRE ()
                }
Lain jika (auto) // kod datang ke sini, membuktikan bahawa ia telah dikonfigurasikan Option.sekali (hanya sekali dilaksanakan), jadi senarai itu jelas
                   senarai = [];
Lain // membuktikan bahawa tiada konfigurasi AUTO, tetapi SEKALI dikonfigurasikan, jadi pengorbanan adalah Dafa muktamad, dan objek panggil balik dimansuhkan terus
                        self.disable();
            };
      var self = {
               add: function () {//Tambah fungsi panggil balik
                        jika (senarai) {
                  var mula = senarai.panjang;
(fungsi addCallback(args) {
setiap (args, fungsi (item) {
Jika (isFunction(item)) {//Jika ia adalah fungsi, tolak senarai panggil balik
                                                                                                                                                                                                                                                                                                                    //Perhatikan bahawa typeof dan Object.prototype.toString adalah berbeza
                              } else if (toString.call(item) === '[object Array]') {//Jika ia adalah tatasusunan, tolak secara rekursif ke dalam senarai panggil balik, penghakiman ini meninggalkan seperti array
                                                                                                                                                                                                                                                                     addCallback(item);
                                                                                                                                                                                 });
                         })(hujah);
                }
Jika (menembak)//Jika fungsi panggil balik sedang dilaksanakan, maka panjang senarai fungsi panggil balik semasa perlu dikemas kini, jika tidak, fungsi panggil balik yang baru ditolak akan diserahkan.
firingLength = senarai.panjang;
                  jika tidak (auto) {//Jika fungsi panggil balik tidak dilaksanakan pada masa ini dan pelaksanaan automatik diperlukan
// Perhatikan bahawa nilai ditugaskan untuk menembak. firingStart = mula;
//Laksanakan rakan kongsi kami yang baru ditambah
api(auto);
                }
                   kembalikan ini;
            },
               fire: function () {//Pencetuskan fungsi panggil balik
                     self.fireWith(ini, hujah);
                   kembalikan ini;
            },
​​​​​​ fireWith: function (context, args) {//Cetus fungsi panggil balik dan nyatakan konteks
//Jika sekali dikonfigurasikan, tindanan tidak akan ditentukan, dan sekali perlu dijamin untuk dilaksanakan sekali sahaja, jadi setelah dilaksanakan sekali, kod di sini tidak akan dilaksanakan lagi
Jika (senarai && (!dipecat || tindanan)) {
//Parameter pembetulan
//Di sini, indeks konteks ialah 0
//Indeks senarai parameter ialah 2
// Menukar kepada akses tatasusunan adalah kerana perwakilan objek menggunakan lebih banyak sumber Terdapat fungsi auto [parameter memori, pelaksanaan automatik] dalam kod fire() peringkat atas Jika objek digunakan, lebih banyak memori akan digunakan
                     args = [konteks,
                                                                                                                                                                                                                                                                                      args.slice && args.slice()
                                                                                                                                                                                                                     ];
api(args);
                }
                   kembalikan ini;
            },
               alih keluar: fungsi () {//Alih keluar fungsi panggil balik
                        jika (senarai) {
setiap (hujah, fungsi (item) {
                      indeks var;
                                        // Es können mehrere Elemente vorhanden sein, der Index kann den Suchbereich in der Schleife darstellen und die zuvor gesuchten Elemente müssen nicht erneut durchsucht werden
While ((index = inArray(item, list, index)) > -1) {
                                          list.splice(index, 1);
Wenn (feuernd) {
//Stellen Sie sicher, dass die oben in Fire ausgeführte Funktionsliste korrekt ausgeführt werden kann. Diese globalen Variablen werden in Fire gesetzt, damit sie asynchron entfernt werden können
If (index <= FiringLength)//Korrekturlänge
FiringLength--;
If (index <= FiringLength)//Korrekturindex
FiringIndex--;
                                                                                               }                                                                                                        }                      });
                }
                   gib dies zurück;
            },
Hat: Funktion (fn) {//Ob es eine Rückruffunktion enthält
                                                                                                        return fn ? inAr ray(fn, list) > -1 : list && list.length;
            },
              empty: function () {//Dieses Rückrufobjekt leeren
list = [];
FiringLength = 0;
                   gib dies zurück;
            },
                deaktivieren: Funktion () {// Zerstören Sie dieses Rückrufobjekt, und die nachfolgende Rückruffunktionsliste wird nicht mehr ausgeführt
                   list = stack = auto = undefiniert;
                   gib dies zurück;
            },
              deaktiviert: Funktion () {//Ob es deaktiviert wurde
 

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
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
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan