Saya rasa setelah dijalankan, itu ada di antrian, tetapi dalam antrian apakah ada jaminan itu akan dipanggil tepat setelah X milidetik? Atau akankah tugas berat lainnya yang lebih tinggi pada antrian akan menunda?
javascript
node.js
serverside-javascript
MyCodeGone
sumber
sumber
Jawaban:
Semantik setTimeout kurang lebih sama seperti di browser web: argumen batas waktu adalah jumlah minimum md yang harus menunggu sebelum dijalankan, bukan jaminan. Selanjutnya, melewatkan 0, bukan angka, atau angka negatif, akan menyebabkannya menunggu dalam jumlah minimum ms. Di Node, ini adalah 1ms, tetapi di browser bisa mencapai 50ms.
Alasannya adalah karena tidak ada preemption JavaScript oleh JavaScript. Pertimbangkan contoh ini:
Alurnya di sini adalah:
Jika bukan ini masalahnya, maka Anda dapat memiliki satu bit JavaScript "mengganggu" yang lain. Kita harus menyiapkan mutex dan semaphor dan semacamnya, untuk mencegah kode seperti ini menjadi sangat sulit untuk dipikirkan:
Single-threadedness dari eksekusi JavaScript Node membuatnya lebih sederhana untuk digunakan daripada kebanyakan gaya konkurensi lainnya. Tentu saja, trade-off adalah bahwa ada kemungkinan bagian program yang berperilaku buruk memblokir semuanya dengan loop tak terbatas.
Apakah ini iblis yang lebih baik untuk berperang daripada kerumitan preemption? Itu tergantung.
sumber
console.log
pesan yang sangat akurat .Gagasan non-pemblokiran adalah bahwa pengulangan iterasi cepat. Jadi, untuk mengulangi setiap centang harus membutuhkan waktu yang cukup singkat sehingga setTimeout akan akurat hingga dalam presisi yang wajar (mungkin mati sekitar <100 ms atau lebih).
Secara teori, Anda benar. Jika saya menulis aplikasi dan memblokir tanda centang, maka setTimeout akan tertunda. Jadi untuk menjawab pertanyaan Anda, siapa yang dapat memastikan setTimeout dijalankan tepat waktu? Anda, dengan menulis kode non-pemblokiran, dapat mengontrol tingkat akurasi hingga hampir semua tingkat akurasi yang wajar.
Selama javascript adalah "single-threaded" dalam hal eksekusi kode (tidak termasuk web-worker dan sejenisnya), itu akan selalu terjadi. Sifat single-threaded adalah penyederhanaan besar dalam banyak kasus, tetapi memerlukan idiom non-blocking agar berhasil.
Coba kode ini di browser atau di node, dan Anda akan melihat bahwa tidak ada jaminan keakuratan, sebaliknya, setTimeout akan sangat terlambat:
Kecuali penerjemah mengoptimalkan pengulangan (yang tidak di chrome), Anda akan mendapatkan ribuan. Hapus loop dan Anda akan melihat 500 di hidung ...
sumber
Satu-satunya cara untuk memastikan kode dieksekusi adalah dengan menempatkan logika setTimeout Anda dalam proses yang berbeda.
Gunakan modul proses anak untuk menelurkan program node.js baru yang menjalankan logika Anda dan meneruskan data ke proses itu melalui semacam aliran (mungkin tcp).
Dengan cara ini bahkan jika beberapa kode pemblokiran yang lama berjalan dalam proses utama Anda, proses anak Anda telah dimulai sendiri dan menempatkan setTimeout dalam proses baru dan utas baru dan dengan demikian akan berjalan saat Anda mengharapkannya.
Komplikasi lebih lanjut berada pada tingkat perangkat keras di mana Anda memiliki lebih banyak utas yang berjalan kemudian proses dan dengan demikian peralihan konteks akan menyebabkan penundaan (sangat kecil) dari waktu yang Anda harapkan. Ini harus diabaikan dan jika itu penting, Anda perlu mempertimbangkan secara serius apa yang coba Anda lakukan, mengapa Anda memerlukan akurasi seperti itu dan perangkat keras alternatif waktu nyata apa yang tersedia untuk melakukan pekerjaan itu.
Secara umum, menggunakan proses anak dan menjalankan beberapa aplikasi node sebagai proses terpisah bersama dengan penyeimbang beban atau penyimpanan data bersama (seperti redis) penting untuk menskalakan kode Anda.
sumber
setTimeout
adalah sejenis Thread , ini memegang operasi untuk waktu tertentu dan mengeksekusi.di sini argumen pertama harus berupa tipe fungsi; sebagai contoh jika Anda ingin mencetak nama Anda setelah 3 detik, kode Anda harus seperti di bawah ini.
Hal penting yang perlu diingat adalah, apa pun yang ingin Anda lakukan dengan menggunakan
setTimeout
metode ini, lakukan di dalam fungsi . Jika Anda ingin memanggil metode lain dengan mengurai beberapa parameter, kode Anda akan terlihat seperti di bawah ini:sumber
setTimeout(callback,t)
digunakan untuk menjalankan panggilan balik setelah setidaknya t milidetik . Penundaan sebenarnya bergantung pada banyak faktor eksternal seperti perincian timer OS dan beban sistem.Jadi, ada kemungkinan akan dipanggil sedikit setelah waktu yang ditentukan, tapi tidak akan pernah dipanggil sebelumnya.
sumber