Bolehkah anda mencari perbezaan antara dua coretan kod di bawah:
function handleClick1() { setTimeout(handleClick1, 0); } function handleClick2() { Promise.resolve().then(handleClick2); }
Jika anda tidak dapat mengenal pasti implikasi memilih satu daripada yang lain, maka catatan blog ini akan mengajar anda sesuatu yang baharu.
setTimeout adalah untuk menjadualkan panggilan balik selepas tempoh masa tertentu. Promise.resolve().then akan melakukan perkara yang sama dengan berkesan, tetapi secara dalaman kedua-duanya berbeza. Yang terakhir mengembalikan janji, yang sudah diselesaikan. Memanggil kemudian(panggilan balik) pada janji itu akan menjadualkan panggilan balik untuk dilaksanakan.
Jadi kedua-dua fungsi di atas memanggil diri mereka secara rekursif dengan kelewatan yang minimum. Perbezaannya ialah panggilan balik daripada setTimeout diletakkan dalam baris gilir macrotask dan panggilan balik dari promise.then() diletakkan dalam baris gilir microtask. Cara gelung acara mengendalikan item daripada dua baris gilir inilah yang menjadikan 2 coretan kod di atas perbezaan.
Semua yang dilakukan oleh gelung acara ialah semasa terdapat tugasan untuk dilaksanakan, ia melaksanakannya dan kemudian tidur dan menunggu tugasan lain.
Macrotasks (atau ringkasnya tugas) termasuk fungsi yang bertanggungjawab untuk kerja seperti:
antara lain...
Selepas pelaksanaan tugas yang dipilih daripada baris gilir tugas, gelung acara melakukan pusat pemeriksaan mikrotugas. Algo untuknya adalah seperti:
While microtask queue is not empty, pick the oldest task from microtask queue and execute it.
Maksudnya ialah jika tugasan mikro memasukkan tugasan mikro lain, tugasan itu akan dilaksanakan sebelum tugasan makro seterusnya. Dan memandangkan pemaparan UI ialah tugasan makro, ia tidak akan dilaksanakan oleh gelung acara.
Berikut ialah demo untuk perkara di atas: JS Bin demo. Animasi tak terhingga sedang berjalan. Jika kami mencetuskan handleClick1 maka kami menambah beberapa pemprosesan pada utas utama, tetapi animasi masih dipaparkan dengan betul. Tetapi jika kita mencetuskan handleClick2 animasi berhenti.
Saya telah menambah pembolehubah totalCount, supaya kita boleh memecahkan sebelum halaman ranap. Tetapi apa yang ketara ialah apabila gelung microTask dimulakan, UI menjadi tidak bertindak balas untuk beberapa lama.. Kerana tugasan seperti rendering, bertindak balas kepada DOM dsb. hanya akan dilaksanakan selepas baris gilir microtask kosong.
Ini menjadikan handleClick1 daripada coretan kod di atas sebagai pilihan yang lebih selamat. Harap blog ini membantu menjelaskan satu perbezaan asas antara tugasan mikro dan tugasan makro.
Atas ialah kandungan terperinci Tingkah laku Penyekatan UI: microtasks vs macrotasks. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!