Definisi
Istilah "asinkron" dapat digunakan dalam arti yang sedikit berbeda, menghasilkan jawaban yang tampaknya bertentangan di sini, sedangkan sebenarnya tidak. Wikipedia di Asynchrony memiliki definisi ini:
Asynchrony, dalam pemrograman komputer, mengacu pada terjadinya peristiwa yang tidak tergantung pada alur program utama dan cara untuk menangani peristiwa tersebut. Ini bisa berupa peristiwa "di luar" seperti kedatangan sinyal, atau tindakan yang dipicu oleh program yang terjadi bersamaan dengan eksekusi program, tanpa pemblokiran program untuk menunggu hasil.
kode non-JavaScript dapat mengantri acara "luar" seperti itu ke beberapa antrean acara JavaScript. Tapi sejauh itulah yang terjadi.
Tanpa Preemption
Tidak ada gangguan eksternal dalam menjalankan kode JavaScript untuk mengeksekusi beberapa kode JavaScript lain dalam skrip Anda. Potongan-potongan JavaScript dieksekusi satu demi satu, dan urutannya ditentukan oleh urutan peristiwa di setiap antrian acara, dan prioritas antrian tersebut.
Misalnya, Anda dapat benar-benar yakin bahwa tidak ada JavaScript lain (dalam skrip yang sama) yang akan pernah dijalankan ketika bagian kode berikut dijalankan:
let a = [1, 4, 15, 7, 2];
let sum = 0;
for (let i = 0; i < a.length; i++) {
sum += a[i];
}
Dengan kata lain, tidak ada preemption dalam JavaScript. Apa pun yang mungkin ada dalam antrian acara, pemrosesan acara tersebut harus menunggu sampai potongan kode tersebut selesai. Spesifikasi EcmaScript mengatakan di bagian 8.4 Pekerjaan dan Antrian Pekerjaan :
Eksekusi suatu Pekerjaan dapat dimulai hanya ketika tidak ada konteks eksekusi yang berjalan dan tumpukan konteks eksekusi kosong.
Contoh Asynchrony
Seperti yang sudah ditulis orang lain, ada beberapa situasi di mana asynchrony berperan dalam JavaScript, dan selalu melibatkan antrian acara, yang hanya dapat menghasilkan eksekusi JavaScript ketika tidak ada eksekusi kode JavaScript lainnya:
setTimeout()
: agen (mis. peramban) akan menempatkan acara dalam antrian acara ketika batas waktu telah kedaluwarsa. Pemantauan waktu dan penempatan acara dalam antrian terjadi oleh kode non-JavaScript, sehingga Anda dapat membayangkan ini terjadi secara paralel dengan potensi eksekusi beberapa kode JavaScript. Tetapi panggilan balik yang disediakan setTimeout
hanya dapat mengeksekusi ketika kode JavaScript yang saat ini dijalankan telah selesai dan antrian acara yang sesuai sedang dibaca.
fetch()
: agen akan menggunakan fungsi OS untuk melakukan permintaan HTTP dan memonitor respons yang masuk. Sekali lagi, tugas non-JavaScript ini dapat berjalan secara paralel dengan beberapa kode JavaScript yang masih dieksekusi. Tetapi prosedur resolusi janji, yang akan menyelesaikan janji yang dikembalikan oleh fetch()
, hanya dapat dijalankan ketika JavaScript yang sedang dijalankan telah selesai.
requestAnimationFrame()
: mesin rendering browser (non-JavaScript) akan menempatkan suatu peristiwa dalam antrian JavaScript saat mesin siap untuk melakukan operasi pengecatan. Ketika acara JavaScript diproses, fungsi panggilan balik dijalankan.
queueMicrotask()
: segera menempatkan acara di antrian mikrotask. Callback akan dieksekusi ketika tumpukan panggilan kosong dan peristiwa itu dikonsumsi.
Ada banyak contoh lagi, tetapi semua fungsi ini disediakan oleh lingkungan host, bukan oleh inti EcmaScript. Dengan inti EcmaScript Anda serempak dapat menempatkan sebuah acara di sebuah Janji Kerja Antrian dengan Promise.resolve()
.
Konstruksi Bahasa
EcmaScript menyediakan beberapa bahasa konstruksi untuk mendukung pola asynchrony, seperti yield
, async
, await
. Tetapi jangan ada kesalahan: kode JavaScript tidak akan terganggu oleh peristiwa eksternal. The "interupsi" yang yield
dan await
tampaknya memberikan hanyalah cara yang terkendali dan telah ditentukan untuk kembali dari panggilan fungsi dan mengembalikan konteks eksekusi nanti, baik dengan kode JS (dalam kasus yield
), atau antrian acara (dalam kasus await
).
Penanganan acara DOM
Ketika kode JavaScript mengakses DOM API, ini dalam beberapa kasus dapat membuat DOM API memicu satu atau lebih pemberitahuan sinkron. Dan jika kode Anda memiliki pengendali acara mendengarkan itu, itu akan dipanggil.
Ini mungkin dianggap sebagai konkurensi pre-emptive, tetapi ini bukan: begitu event handler Anda kembali, API DOM akhirnya juga akan kembali, dan kode JavaScript asli akan berlanjut.
Dalam kasus lain, DOM API hanya akan mengirimkan acara dalam antrian acara yang sesuai, dan JavaScript akan mengambilnya setelah tumpukan panggilan dikosongkan.
Lihat acara sinkron dan asinkron