Apakah ada cara yang lebih baik untuk merekayasa sleep
dalam JavaScript daripada pausecomp
fungsi berikut ( diambil dari sini )?
function pausecomp(millis)
{
var date = new Date();
var curDate = null;
do { curDate = new Date(); }
while(curDate-date < millis);
}
Ini bukan duplikat Tidur di JavaScript - penundaan antar tindakan ; Saya ingin tidur nyata di tengah fungsi, dan bukan penundaan sebelum sepotong kode dijalankan.
javascript
sleep
fmsf
sumber
sumber
Jawaban:
2017 - 2019 pembaruan
Sejak 2009 ketika pertanyaan ini diajukan, JavaScript telah berevolusi secara signifikan. Semua jawaban lain sekarang sudah usang atau terlalu rumit. Inilah praktik terbaik saat ini:
Ini dia.
await sleep(<duration>)
.Atau sebagai one-liner:
Perhatikan bahwa,
await
hanya dapat dieksekusi dalam fungsi yang diawali denganasync
kata kunci, atau di tingkat atas skrip Anda di beberapa lingkungan (mis. konsol Chrome DevTools, atau Runkit).await
hanya menjedaasync
fungsi saat iniDua fitur JavaScript baru membantu menulis fungsi "tidur" ini:
async/await
fitur memungkinkan kode eksplisit menunggu janji untuk menetap (tekad atau menolak).Kesesuaian
async
/await
mendarat di V8 dan telah diaktifkan secara default sejak Chrome 55 (dirilis pada Des 2016)Jika karena alasan yang aneh Anda menggunakan Node yang lebih tua dari 7 (yang telah mencapai akhir masa pakai ), atau menargetkan browser lama,
async
/await
masih dapat digunakan melalui Babel (alat yang akan mengubah - ubah JavaScript + fitur-fitur baru menjadi JavaScript lama biasa) , dengantransform-async-to-generator
plugin.sumber
(Lihat jawaban yang diperbarui untuk 2016 )
Saya pikir sangat masuk akal untuk ingin melakukan suatu tindakan, tunggu, lalu lakukan tindakan lain. Jika Anda terbiasa menulis dalam bahasa multi-utas, Anda mungkin memiliki ide untuk menghasilkan eksekusi untuk waktu yang ditentukan hingga utas Anda terbangun.
Masalahnya di sini adalah bahwa JavaScript adalah model berbasis peristiwa single-thread. Sementara dalam kasus tertentu, mungkin menyenangkan untuk membiarkan seluruh mesin menunggu beberapa detik, secara umum itu adalah praktik yang buruk. Misalkan saya ingin memanfaatkan fungsi Anda saat menulis sendiri? Ketika saya memanggil metode Anda, metode saya akan membeku. Jika JavaScript entah bagaimana dapat mempertahankan konteks eksekusi fungsi Anda, simpan di suatu tempat, lalu bawa kembali dan lanjutkan kemudian, maka tidur dapat terjadi, tetapi itu pada dasarnya adalah threading.
Jadi, Anda cukup terjebak dengan apa yang disarankan orang lain - Anda harus memecah kode Anda menjadi beberapa fungsi.
Pertanyaan Anda agak salah pilihan, kalau begitu. Tidak ada cara untuk tidur dengan cara yang Anda inginkan, Anda juga tidak harus mengejar solusi yang Anda sarankan.
sumber
sleep()
tidak mungkin di JS, dan sebagian besar waktu ada cara yang lebih baik untuk melakukan sesuatu. Tapi saya masih menganggap cara mesin mengikat semua hal menjadi cacat desain; tidak ada alasan bahasa tidak dapat memilikisleep()
fungsi terbatas pada skrip, halaman, atau fungsi tertentu tanpa mesin menghancurkan CPU dan membekukan aplikasi seperti orang gila. Ini tahun 2015 dan Anda seharusnya tidak dapat merusak seluruh peramban webwhile(1)
. Kami memiliki Flash untuk hal-hal seperti itu.Dalam JavaScript, saya menulis ulang setiap fungsi sehingga bisa berakhir sesegera mungkin. Anda ingin browser kembali dalam kendali sehingga dapat membuat perubahan DOM Anda.
Setiap kali saya ingin tidur di tengah-tengah fungsi saya, saya refactored untuk menggunakan a
setTimeout()
.Edit
Tidur nyenyak, atau menunda, fungsi dalam bahasa apa pun banyak diperdebatkan. Beberapa akan mengatakan bahwa harus selalu ada sinyal atau panggilan balik untuk mengaktifkan fungsionalitas yang diberikan, yang lain akan berpendapat bahwa kadang-kadang momen penundaan yang sewenang-wenang berguna. Saya mengatakan bahwa untuk masing-masing aturan mereka sendiri dan satu tidak pernah bisa mendikte apa pun dalam industri ini.
Menulis fungsi tidur itu sederhana dan menjadikannya lebih bisa digunakan dengan Janji JavaScript:
sumber
function foobar(el) { setTimeout(function() { foobar_cont(el); }, 5000); }
Hanya untuk debug / dev , saya memposting ini jika berguna bagi seseorang
Hal menarik, di Firebug (& mungkin konsol js lain), tidak ada yang terjadi setelah menekan enter, hanya setelah durasi tidur yang ditentukan (...)
Contoh penggunaan:
sumber
only for debug/dev
... rolleyesSaya setuju dengan poster yang lain, tidur yang sibuk hanya ide yang buruk.
Namun, setTimeout tidak menahan eksekusi, ia mengeksekusi baris berikutnya dari fungsi segera setelah batas waktu SET, bukan setelah batas waktu berakhir, sehingga tidak menyelesaikan tugas yang sama dengan yang akan dilakukan tidur.
Cara untuk melakukannya adalah dengan memecah fungsi Anda menjadi sebelum dan sesudah bagian.
Pastikan nama fungsi Anda masih menggambarkan secara akurat apa yang dilakukan masing-masing bagian (IE GatherInputThenWait dan CheckInput, daripada funcPart1 dan funcPart2)
Edit
Metode ini mencapai tujuan untuk tidak mengeksekusi baris kode yang Anda putuskan sampai SETELAH batas waktu Anda, sambil tetap mengembalikan kontrol ke PC klien untuk mengeksekusi apa pun yang telah ia antri.
Edit Lebih Lanjut
Seperti yang ditunjukkan dalam komentar, ini sama sekali TIDAK BEKERJA dalam satu lingkaran. Anda bisa melakukan peretasan (jelek) yang bagus untuk membuatnya bekerja dalam satu lingkaran, tetapi secara umum itu hanya akan membuat kode spageti bencana.
sumber
function foo(index) { setTimeout(function() { foo_continue(index); }, 10000); }
danfor(var X = 0; X < 3;X++) { foo(X); }
- nilai X dilewatkan ke dalamfoo
, yang kemudian akan digunakan kembali dengan namaindex
kapanfoo_continue
akhirnya dipanggil.console.log()
dalam kefoo_continue()
dalam versi setTimeout dan Anda mendapatkan hasil yang sama.Untuk cinta $ DEITY tolong jangan membuat fungsi tidur sibuk-menunggu.
setTimeout
dansetInterval
lakukan semua yang Anda butuhkan.Setiap dua detik interval sembunyikan teks selama satu detik. Ini menunjukkan cara menggunakan setInterval dan setTimeout untuk menampilkan dan menyembunyikan teks setiap detik.
sumber
Saya tahu ini sedikit pertanyaan lama, tetapi jika (seperti saya) Anda menggunakan Javascript dengan Badak, Anda dapat menggunakan ...
sumber
Jika Anda menggunakan jQuery, seseorang benar-benar membuat plugin "delay" yang tidak lebih dari pembungkus untuk setTimeout:
Anda kemudian dapat menggunakannya dalam deretan panggilan fungsi seperti yang diharapkan:
sumber
.delay()
adalah bagian dari jQuery (meskipun dengan semantik berbeda dari implementasi di atas). api.jquery.com/delaySaya telah mencari solusi tidur juga (bukan untuk kode produksi, hanya untuk dev / tes) dan menemukan artikel ini:
http://narayanraman.blogspot.com/2005/12/javascript-sleep-or-wait.html
... dan inilah tautan lain dengan solusi sisi klien: http://www.devcheater.com/
Selain itu, saat Anda menelepon
alert()
, kode Anda juga akan dijeda, saat peringatan ditampilkan - perlu menemukan cara untuk tidak menampilkan peringatan tetapi mendapatkan efek yang sama. :)sumber
Berikut adalah solusi sederhana menggunakan XMLHttpRequest sinkron:
isi dari sleep.php:
Sebut sekarang dengan: sleep (5);
sumber
setTimeout()
jika itu berhasil, tetapi jika melakukannya berarti mengurai 1000 baris panggilan balik ini mungkin mulai tidak terlihat seperti lelucon.sleep(300)
dan situs web membutuhkan 150 ms untuk tanggapan daripada kode javascript akan tidur selama 450 ms. dan jika koneksi internet terputus oleh browser, itu akan berfungsi hanya 0ms. Jadi itu bukan solusi yang lebih baikIni dia Seperti yang tertulis dalam kode, jangan menjadi pengembang yang buruk dan gunakan ini di situs web. Ini adalah fungsi utilitas pengembangan.
sumber
async/await
sayangnya tidak responsif, dan kita harus menggunakannya secara wajib.Saya pribadi suka yang sederhana:
kemudian:
Saya menggunakannya sepanjang waktu untuk membuat waktu pemuatan palsu saat membuat skrip dalam P5js
sumber
Pertama:
Tentukan fungsi yang ingin Anda jalankan seperti ini:
Kemudian jadwalkan eksekusi dengan metode setTimeout:
Catat dua hal
sumber
pastikan fungsi panggilan Anda async
diverifikasi dan berfungsi dengan baik
sumber
Solusi yang lebih baik untuk membuat segala sesuatu tampak seperti apa yang diinginkan kebanyakan orang adalah dengan menggunakan fungsi anonim:
Ini mungkin yang paling dekat Anda akan mendapatkan sesuatu yang hanya melakukan apa yang Anda inginkan.
Catatan, jika Anda membutuhkan beberapa tidur, ini bisa menjadi terburu-buru dan Anda mungkin benar-benar perlu memikirkan kembali desain Anda.
sumber
Untuk browser, saya setuju bahwa setTimeout dan setInterval adalah cara yang harus dilakukan.
Tetapi untuk kode sisi server, mungkin memerlukan fungsi pemblokiran (misalnya, agar Anda dapat secara efektif melakukan sinkronisasi utas).
Jika Anda menggunakan node.js dan meteor, Anda mungkin mengalami keterbatasan dalam menggunakan setTimeout di fiber. Berikut adalah kode untuk tidur sisi server.
Lihat: https://github.com/laverdet/node-fibers#sleep
sumber
Server may require a blocking function
... Saya tidak melihat betapa kuatnya memblokir satu-satunya utas Node dan membuat seluruh server Anda tidak responsif selama beberapa detik adalah ide yang bagus, tetapi apa punSaya akan merangkum setTimeOut dalam Janji untuk konsistensi kode dengan tugas asinkron lainnya: Demo di Fiddle
Digunakan seperti itu:
Mudah untuk mengingat sintaksis jika Anda menggunakan Janji.
sumber
Pembaruan 2019 menggunakan Atomics.wait
Harus bekerja di Node 9.3 atau lebih tinggi.
Saya membutuhkan pengatur waktu yang cukup akurat di Node.js dan itu berfungsi dengan baik untuk itu. Namun sepertinya ada dukungan yang sangat terbatas di browser.
Menjalankan beberapa tolok ukur waktu 10 detik.
Dengan setTimeout saya mendapatkan kesalahan hingga 7000 mikrodetik. (7ms)
Dengan Atomics, kesalahan saya tampaknya tetap di bawah 600 mikrodetik. (0,6 ms)
Pembaruan 2020: Dalam Ringkasan
dimana halaman sisi server, misalnya
sleep.jsp
, terlihat sepertisumber
Sebagian besar jawaban di sini salah arah atau paling tidak ketinggalan jaman. Tidak ada alasan javascript harus berulir tunggal, dan memang tidak. Hari ini semua browser utama mendukung pekerja, sebelum ini adalah kasus runtime javascript lain seperti Rhino dan Node.js mendukung multithreading.
'Javascript adalah utas tunggal' bukan jawaban yang valid. Misalnya menjalankan fungsi tidur di dalam pekerja tidak akan memblokir kode yang berjalan di utas ui.
Di runtimes yang lebih baru yang mendukung generator dan hasil, seseorang dapat membawa fungsionalitas yang mirip dengan fungsi tidur di lingkungan berulir tunggal:
Ini imitasi tidur berbeda dari fungsi tidur yang benar karena tidak menghalangi utas. Ini hanyalah gula di atas fungsi setTimeout javascript saat ini. Jenis fungsi ini telah diterapkan di Task.js dan harus berfungsi hari ini di Firefox.
sumber
sleep
menggunakan banyak pekerja. Jika menggunakan fungsi generator Node.js sudah diterapkan dan dapat digunakan seperti yang dijelaskan. Peramban arus utama belum semua generator yang diimplementasikan pada hari ini.Saya telah mencari / menelusuri beberapa halaman web di javascript sleep / wait ... dan TIDAK ada jawaban jika Anda ingin javascript "RUN, DELAY, RUN" ... apa yang kebanyakan orang dapatkan adalah, "RUN, RUN (tidak berguna) barang), RUN "atau" RUN, RUN + menunda RUN "....
Jadi saya makan burger dan berpikir ::: di sini adalah solusi yang berfungsi ... tetapi Anda harus memotong kode yang sedang berjalan ... ::: ya, saya tahu, ini hanya lebih mudah untuk membaca refactoring .. masih ...
//......................................... //Contoh 1:
// .................................... // example2:
// ................. example3:
// .............. example4:
sumber
sumber
Solusi terpendek tanpa ketergantungan:
sumber
await new Promise(function(resolve) { setTimeout(resolve, 5000); });
Anda tidak dapat tidur seperti itu di JavaScript, atau, lebih tepatnya, Anda tidak boleh tidur. Menjalankan sleep atau loop sementara akan menyebabkan browser pengguna menggantung sampai loop selesai.
Gunakan timer, seperti ditentukan dalam tautan yang Anda referensikan.
sumber
Salah satu skenario di mana Anda mungkin menginginkan fungsi sleep () daripada menggunakan setTimeout () adalah jika Anda memiliki fungsi menanggapi klik pengguna yang pada akhirnya akan membuka jendela baru yaitu jendela popup dan Anda telah memulai beberapa pemrosesan yang memerlukan periode singkat untuk menyelesaikan sebelum popup ditampilkan. Memindahkan jendela yang terbuka menjadi penutup berarti jendela itu biasanya diblokir oleh browser.
sumber
Saya dapat memahami tujuan fungsi tidur jika Anda harus berurusan dengan eksekusi yang sinkron. Fungsi setInterval dan setTimeout membuat utas eksekusi paralel yang mengembalikan urutan eksekusi kembali ke program utama, yang tidak efektif jika Anda harus menunggu hasil yang diberikan. Tentu saja seseorang dapat menggunakan acara dan penangan, tetapi dalam beberapa kasus bukan itu yang dimaksudkan.
sumber
Menambahkan dua bit saya. Saya perlu menunggu-tunggu untuk keperluan pengujian. Saya tidak ingin membagi kode karena itu akan banyak pekerjaan, jadi sederhana untuk melakukannya untuk saya.
Saya tidak melihat kelemahan dalam melakukan ini dan itu berhasil bagi saya.
sumber
for
loop hampir selalu akan segera dieksekusi, terlepas dari nilai maks untuki
, dan bahkan dengan kode matematika yang rumit ditempatkan di dalamnya. Jadi, kecuali Anda hanya menunggu beberapa milidetik, tampaknya masih tidak ada cara untuk tidur dengan anggun di JS.Ini dapat dilakukan dengan menggunakan metode tidur Java. Saya sudah mengujinya di FF dan IE dan tidak mengunci komputer, mengunyah sumber daya, atau menyebabkan hit server tanpa akhir. Sepertinya solusi bersih bagi saya.
Pertama, Anda harus mendapatkan Java dimuat pada halaman dan membuat metodenya tersedia. Untuk melakukan itu, saya melakukan ini:
Kemudian, yang harus Anda lakukan ketika Anda ingin jeda tanpa rasa sakit di JS Anda adalah:
Di mana xxx adalah waktu dalam milidetik. Dalam kasus saya (dengan alasan pembenaran), ini adalah bagian dari pemenuhan pesanan back-end di perusahaan yang sangat kecil dan saya perlu mencetak faktur yang harus dimuat dari server. Saya melakukannya dengan memuat faktur (sebagai halaman web) ke dalam iFrame dan kemudian mencetak iFrame. Tentu saja, saya harus menunggu sampai halaman dimuat sepenuhnya sebelum saya bisa mencetak, sehingga JS harus berhenti. Saya menyelesaikan ini dengan memiliki halaman faktur (di iFrame) mengubah bidang formulir tersembunyi pada halaman induk dengan acara onLoad. Dan kode pada halaman induk untuk mencetak faktur tampak seperti ini (bagian yang tidak relevan dipotong untuk kejelasan):
Jadi pengguna menekan tombol, skrip memuat halaman faktur, lalu menunggu, memeriksa setiap seperempat detik untuk melihat apakah halaman faktur selesai memuat, lalu muncul dialog cetak agar pengguna mengirimnya ke printer. QED.
sumber
Banyak jawaban tidak (langsung) menjawab pertanyaan, dan begitu juga yang ini ...
Inilah dua sen (atau fungsi) saya:
Jika Anda ingin fungsi yang kurang kikuk daripada
setTimeout
dansetInterval
, Anda bisa membungkusnya dalam fungsi yang hanya membalik urutan argumen dan memberi mereka nama yang bagus:Versi CoffeeScript:
Anda kemudian dapat menggunakannya dengan baik dengan fungsi anonim:
Sekarang terbaca dengan mudah sebagai "setelah N milidetik, ..." (atau "setiap N milidetik, ...")
sumber
Untuk kasus tertentu yang ingin menghilangkan ruang panggilan yang dieksekusi oleh loop, Anda dapat menggunakan sesuatu seperti kode di bawah ini dengan prototipe. Tanpa prototipe, Anda dapat mengganti fungsi penundaan dengan setTimeout.
sumber
Jika Anda menggunakan node.js, Anda dapat melihat serat - ekstensi C asli ke simpul, simulasi yang agak multi-threading.
Hal ini memungkinkan Anda untuk melakukan yang nyata
sleep
dengan cara yang memblokir eksekusi dalam serat, tetapi tidak menghalangi di utas utama dan serat lainnya.Berikut adalah contoh baru dari readme mereka sendiri:
- dan hasilnya adalah:
sumber