Pekerja web khusus (pekerja web khusus) menyediakan cara sederhana untuk memungkinkan konten web menjalankan skrip di latar belakang. Setelah pekerja dibuat, ia dapat menyampaikan pesan ke fungsi pemantauan acara yang ditentukan oleh penciptanya, sehingga semua tugas yang dihasilkan oleh pekerja akan menerima pesan -pesan ini. Utas pekerja dapat melakukan tugas tanpa interferensi UI. Selain itu, ia juga dapat menggunakan XMLHTTPREQUEST (meskipun dua nilai atribut responsexml dan saluran selalu nol) untuk melakukan operasi I/O. Artikel ini memberikan contoh dan detail untuk membuat dokumen sebelumnya. Fungsi yang diberikan kepada Pekerja mencantumkan fungsi yang didukung oleh pekerja.
Antarmuka pekerja akan menghasilkan utas sistem operasi nyata. Namun, untuk pekerja web, titik komunikasi dengan utas lain akan dikendalikan dengan cermat, yang berarti sulit bagi Anda untuk menyebabkan komplikasi. Anda tidak memiliki cara untuk mengakses komponen keamanan atau DOM non -utusan. Jadi jika Anda tidak menghabiskan usaha, Anda tidak dapat melakukan kesalahan. Menghasilkan pekerja
Sangat mudah untuk menciptakan pekerja baru. Yang harus Anda lakukan adalah memanggil konstruktor pekerja (), dan menentukan URI yang perlu menjalankan skrip yang berjalan di utas pekerja. Fungsi pemrosesan acara tertentu.
var myworker = pekerja baru (my_task.js);
Atau, Anda juga dapat menggunakan AddEventListener ():
var myworker = pekerja baru (my_task.js); Pekerja.
Baris pertama dalam contoh menciptakan utas pekerja baru. Tindakan ketiga menetapkan fungsi pemantauan dari acara pesan. Ketika pekerja menyebut fungsi postmessage () sendiri, fungsi pemrosesan acara ini dipanggil. Akhirnya, utas pekerja diluncurkan di baris ketujuh. Catatan: Parameter URI yang mentransmisikan konstruktor pekerja harus mengikuti strategi homolog. Saat ini, produsen browser yang berbeda masih berbeda tentang URI mana yang harus mengikuti strategi homolog; Blob Uri.
Lulus dataData yang ditransmisikan antara beranda dan pekerja disalin, tidak dibagikan. Objek yang diteruskan ke pekerja perlu diserialisasi, dan kemudian ujung berikutnya perlu diserialisasi. Halaman tidak berbagi contoh yang sama dengan pekerja. Sebagian besar browser menggunakan salinan terstruktur untuk mencapai fitur ini.
Sebelum turun, untuk tujuan mengajar, mari kita membuat fungsi yang disebut emulatingMessage ().
Fungsi emulatingmessage (vval) {return eval; // objectalert (typeOf emulatingMessage (example1); // number // test #2var example2 = true; alert (typeof example2); // booleanalert (tipeof emulatingMessage (contoh2)); / Boolean // Tes #3V #3V AR Contoh3 = String baru (Hello World); , 43}; Var example5 = hewan baru (kucing, 3);Nilai yang tidak dibagikan disebut pesan. Mari kita bicara tentang pekerja, Anda dapat menggunakan postmessage () untuk menyampaikan pesan ke utas utama atau mengirimkannya kembali dari utas utama. Atribut data dari acara pesan berisi data dari pekerja.
Contoh.html: (beranda):var myworker = pekerja baru (my_task.js); ;
CATATAN: Secara umum, latar belakang utas -termasuk pekerja -tidak dapat mengoperasikan DOM. Jika utas latar perlu memodifikasi DOM, maka ia harus mengirim pesan ke pendirinya sehingga pencipta untuk menyelesaikan operasi ini.
Seperti yang Anda lihat, pesan yang dikirim antara pekerja dan beranda selalu "pesan JSON", bahkan jika itu adalah jenis nilai asli. Oleh karena itu, Anda dapat mengirimkan data JSON dan/atau tipe data apa pun yang dapat membuat serial:
PostMessage ({cmd: init, timestamp: date.now ()});Contoh untuk lulus data
Contoh#1: Buat "eval asinkron ()" yang umum
Contoh berikut memperkenalkan cara menggunakan eval () pada pekerja untuk menjalankan semua jenis kode JavaScript dalam semua jenis asinkron dalam urutan ::
// sintaks: asynceval (kode [, listner]) var asynceval = (function () {var aliskener = [], oparser = pekerja baru (data: teks/javascript; charset = us-asciii, onmessage%20%3d%20 fungsi 20 %20%28oevent%29%20%7b%0a%09 PostMessage%28%7b%09%09%22%22%20OEVENT.Data%2C%09%22%Permalti 22%3A 3A 3A 3A 3A 3A 3A 3A 3A%% 20eval%28oevent.data.code%29%0a%09%7d%29%3b%0a%7d); Data.id] (Eevent.data.evaluate);} Hapus AlisTeners [eevent.data.id];}; : Alisteners.length -1, kode: scode});};});Contoh Penggunaan:
// pesan peringatan asinkron ... asynceval (3 + 2, function (smessage) {waspada (3 + 2 = + smessage); // cetak asinkron ... asynceval (// halo dunia !!!/,,, fungsi (Shtml) {document.body.appendChild (document.createTextNode (shtml);}); .open (/get/, /http://www.mozilla.org//, false);/n/toreq.send (null);/n/treturn oreq.responsetext;/n});));) );););););););););););););););););););););););Contoh#2: Transfer metode lanjutan JSON dan buat sistem pertukaran
Jika Anda perlu mengirimkan data yang sangat rumit, dan Anda perlu memanggil beberapa metode di beranda dan pekerja pada saat yang sama, maka Anda dapat mempertimbangkan untuk membuat sistem yang mirip dengan yang berikut.
Example.html (halaman utama): <! Argumen untuk lulus 1, argumen untuk lulus 2, dll. Fungsi): Menambahkan pendengar * RemoveListener (Nama): Menghapus Properti Instance Listener Queeryker: * DefaultListListener: ExecuteM pendengar default hanya ketika pekerja memanggil postmessage () Function secara langsung */ fungsi Queryable (surl, fdeflistener, fonerror) {variery Oinstance = this, oworcer = pekerja baru (surl), olistener = {}; .data.hasownproperty (rnb93qh) {olisteners [eevent.data.vo42t30] .Apply (oevent.data.rnb99 3qh);} else {this.defaultlisten.call (oinstance, oevent.data); {owster.onError = fonerror;} this.sendQuery = function (/ * nama fungsi yang dapat diperoleh, argumen untuk lulus 1, argumen untuk lulus 2, 2, 2, dll. Lemparkan Typerror Baru (QueryableWorker.SendQuery -Tidak cukup argumen); = Function (vmsg) {// Saya hanya berpikir tidak perlu menggunakan panggilan () bagaimana dengan baru saja (vmsg); Prototy worker.prototype.postmessage.call (oworker, vmsg); = Flistener;}; ] * /); // pendengar khusus Anda omytask.addlistener (printsometh ing, function (nResult) {document.geteLementById (firstLink) .parentnode.appendChild (document.createTextNode (tampilannya adalah + nResult +!);});} ); A ID = FirstLink href = JavaScript: omytask.sendQuery ('getDifferente', 5, 3);> Apa perbedaan antara 5 dan 3? omytask.sendQuery ('waitsomething'); ) {// Do Something} funct} funct ion myprivateFunc2 () {// Do Something} // dll. Dapatkan perbedaan taruhan ween dua nightrs: getDifference: function (nminund, nsubtrahend) {reply (printsomething, nminuend -nsubtrahend);}, // Contoh #2: tunggu tiga detik waitsomething: function () {setMimeout (function () {alererer Tsomething, 3, jenis kelamin);}, 3000);}}; (/ * Nama pendengar, argumen untuk lulus 1, argumen untuk lulus 2, dll : Argumen [0], rnb93qh: array.prototype.slice .call (argumen, 1)});} onMessage = function (oevent) {if (eevent.data objek && sownproperty) && daeenproprty (bk4e1h0) .has) && Daeenproprty (bk4e1h0) .has) && Daeenproprty (bk4e1h0) .has) && Daeenproprty (bk4e1h0) .has) (has) (BK4E1H0). {queryableFunction [eevent.data .bk4e1h0] .Apply (self, oevent.data.ktp3fm1);} else {defaultQuery (eevent.data);}};Ini adalah metode yang sangat cocok untuk mengalihkan berita antara beranda-pekerja-atau sebaliknya-sebaliknya.
Transfer data dengan mentransfer kepemilikan (objek yang dapat ditransfer)
Google Chrome 17 dan Firefox 18 menyertakan metode lain dengan kinerja yang lebih tinggi untuk meneruskan jenis objek tertentu (objek yang dapat ditransfer) kepada pekerja/kembali dari pekerja. Objek transfer ditransfer dari satu konteks ke konteks lain tanpa operasi salinan. Ini berarti akan mendapatkan peningkatan kinerja yang hebat saat melewati data besar. Jika Anda berasal dari dunia C/C ++, maka bayangkan itu sebagai transmisi menurut referensi. Namun, tidak seperti pengangkutan sesuai dengan referensi, setelah objek ditransfer, versi bahwa konteks asli tidak akan ada lagi. Kepemilikan objek ditransfer ke konteks baru. Misalnya, ketika Anda mentransfer objek ArrayBuffer dari aplikasi utama ke pekerja, arraybuffer asli dihapus dan tidak dapat digunakan. Konten yang dikandungnya (lengkap) akan diteruskan ke konteks pekerja.
// Buat file 32MB dan isi.var uint8Array = uint8aray baru (1024*1024*32); ;} worker.postmessage (uint8Array.buffer, [uint8aray.buffer]);Menghasilkan subworker
Jika perlu, pekerja dapat menghasilkan lebih banyak pekerja. Ini disebut subworker, yang harus di -host di sumber yang sama dengan halaman induk. Dengan cara yang sama, subworker menganalisis alamat URI daripada halamannya sendiri, bukan halamannya sendiri. Ini membuat pekerja dengan mudah memantau ketergantungan mereka. Chrome tidak mendukung subworker.
Pekerja tertanamSaat ini tidak ada metode "resmi" yang dapat menyematkan kode pekerja ke halaman web seperti elemen <script>. Tetapi jika elemen <script> tidak memiliki karakteristik SRC, dan karakteristik jenisnya tidak ditentukan sebagai tipe MIME yang sedang berjalan, maka itu akan dianggap sebagai elemen blok data dan dapat digunakan oleh JavaScript. "Blok Data" adalah fitur yang sangat umum di HTML5, yang dapat membawa hampir semua jenis data jenis teks. Karena itu, Anda dapat menanamkan pekerja dengan cara berikut:
<! Analisis mesin, karena tipe-mime adalah pekerja/JS-pekerja. Var myvar = halo dunia!; </script> <script type = text/javascript> // skrip akan dianalisis oleh mesin JS karena tipe-mime-nya adalah teks/javascript. Function pagelog (smsg) {// Gunakan fragmen: dengan cara ini, browser hanya akan rendering/reading. var ofragm = document.createDocumentFragment (); -Workr> // Script ini tidak akan diuraikan oleh mesin JS karena tipe mime-nya adalah teks/JS-pekerja. onMessage = function (oevent) {postmessage (myvar);}; // Kode pekerja yang tersisa ditulis di sini. </script> <script type = text/javascript> // skrip akan dianalisis oleh mesin JS karena tipe-mime-nya adalah teks/javascript. // Di masa lalu ...: // kami menggunakan blob builder // ... tapi sekarang kami menggunakan blob ...: var blob = new blob (array.prototype.map.call (documens.quelyselectorary (skrip [tipe [type = =/text // js- workr/], function (oscript) {return oscript.textContent;}), {type: text/javascript}); Skrip S- Pekerja. document.worker = pekerja baru (window.url.createObjectUrl (blob)); () {document.worker.postmessage ();};Sekarang, pekerja tertanam telah ditetapkan ke dalam dokumen yang disesuaikan. Properti pekerja.
Batas waktu dan intervalPekerja dapat menggunakan batas waktu dan interval seperti utas utama. Ini akan sangat berguna, misalnya, jika Anda ingin utas pekerja secara berkala tanpa kode berjalan tanpa gangguan.
Pekerja PengakhiranJika Anda ingin segera mengakhiri pekerja, Anda dapat menghubungi metode penghentian () pekerja ::
myworker.terminate ();
Utas pekerja akan segera dibunuh dan tidak akan meninggalkan kesempatan apa pun untuk membiarkannya menyelesaikan operasinya sendiri atau pekerjaan pembersihan.
Pekerja juga dapat menghubungi metode NSIWorkerscope.close () Anda sendiri untuk menutup diri Anda:
self.close ();Kesalahan proses
Ketika pekerja adalah kesalahan runtime, fungsi pemrosesan acara OnError dipanggil. Ini menerima peristiwa yang mengimplementasikan kesalahan nama antarmuka ERROREVENT. Kejadian tidak akan menggelegak dan dapat dibatalkan; Acara kesalahan memiliki tiga bidang berikut yang tertarik pada:
PesanPesan kesalahan yang dapat dibaca.
nama fileNama file skrip kesalahan.
linenoNomor baris file skrip saat kesalahan terjadi.
Kunjungi Objek NavigatorPekerja dapat mengakses objek navigator dalam ruang lingkupnya. Ini berisi string berikut yang dapat mengenali browser, seperti melakukannya dalam skrip biasa:
Utas pekerja dapat mengakses fungsi global, ImportScripts (), yang memungkinkan pekerja untuk memperkenalkan skrip atau perpustakaan ke dalam ruang lingkupnya sendiri. Anda dapat memperkenalkan URI tanpa melewati parameter, atau ke URI dari beberapa skrip;
ImportScripts (); */
Browser memuat dan menjalankan skrip. Objek global dalam setiap skrip dapat digunakan oleh pekerja. Jika skrip tidak dapat dimuat, pengecualian jaringan_error akan dilemparkan, dan kode berikutnya tidak akan dieksekusi. Kode yang sebelumnya dijalankan (termasuk kode yang dieksekusi menggunakan window.setTimeout ()) masih dapat digunakan. Deklarasi fungsi setelah ImportScripts () masih dapat digunakan karena mereka selalu berjalan sebelum kode lain. Catatan: Urutan unduhan skrip tidak diperbaiki, tetapi pesanan akan diteruskan ke ImportScripts () () saat dieksekusi. Ini diselesaikan secara bersamaan; sampai semua skrip diunduh dan dijalankan, ImportScripts () akan kembali.
contohBagian ini memberikan beberapa contoh cara menggunakan pekerja DOM.
Menjalankan operasi di latar belakang
Salah satu keunggulan pekerja adalah bahwa ia dapat menjalankan operasi padat prosesor tanpa memblokir utas UI. Dalam contoh berikut, pekerja digunakan untuk menghitung Fibona.
Kode JavaScript
Kode JavaScript berikut disimpan dalam file "Fibonacci.js", yang dikaitkan dengan file HTML di bagian berikutnya.
Var result = []; function errorreceiver (event) {throw event.data;} onmessage = function (event) {var n = parseInt (event.data); } Untuk (var i = 1; i <= 2; i ++) {var pekerja = pekerja baru (fibonacci.js);Pekerja mengatur atribut onMessage ke suatu fungsi. (Perhatikan bahwa penggunaan ini tidak sama dengan mendefinisikan variabel global dengan nama yang sama, atau fungsi dengan nama yang sama. Pesan yang dikirim oleh halaman web.) Ini akan memungkinkan rekursi dan menghasilkan salinan baru Anda untuk memproses setiap siklus perhitungan.
Kode HTML
<! = pekerja baru (fibonacci.js); = function (error) {dump (kesalahan pekerja: + error.message +/n);Halaman web membuat elemen div, ID adalah hasil, menggunakannya untuk menampilkan hasil perhitungan, dan kemudian menghasilkan pekerja. Setelah menghasilkan pekerja, fungsi pemrosesan OnMessage dikonfigurasi untuk menampilkan hasil perhitungan dengan mengatur konten elemen div, dan kemudian fungsi pemrosesan OnError diatur ke informasi kesalahan penyimpanan. Akhirnya, kirim pesan ke pekerja untuk memulainya.