Pertanyaan Apa versi JavaScript tidur ()?


Apakah ada cara yang lebih baik untuk merekayasa sleep di JavaScript daripada yang berikut pausecomp fungsi (diambil dari sini)?

function pausecomp(millis)
{
    var date = new Date();
    var curDate = null;
    do { curDate = new Date(); }
    while(curDate-date < millis);
}

Ini bukan duplikat dari Tidur di JavaScript - jeda di antara tindakan; aku ingin sebuah tidur nyenyak di tengah-tengah fungsi, dan bukan penundaan sebelum potongan kode dijalankan.


1519
2017-10-07 09:44


asal


Jawaban:


Pembaruan 2017

Sejak tahun 2009 ketika pertanyaan ini diajukan, JavaScript telah berkembang secara signifikan. Semua jawaban lain sekarang sudah usang atau terlalu rumit. Berikut adalah praktik terbaik saat ini:

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function demo() {
  console.log('Taking a break...');
  await sleep(2000);
  console.log('Two second later');
}

demo();

Ini dia. await sleep(<duration>).

Anda dapat mencoba kode ini secara langsung di Runkit. Perhatikan itu,

  1. await hanya dapat dijalankan dalam fungsi yang diawali dengan async kata kunci. Runkit membungkus kode Anda dalam fungsi async sebelum mengeksekusinya.
  2. await hanya berhenti saat ini async fungsi

Dua fitur JavaScript baru membantu menulis fungsi "tidur" yang sebenarnya ini:

Kesesuaian

Jika karena suatu alasan Anda menggunakan Node yang lebih tua dari 7, atau menargetkan peramban lama, async/await masih bisa digunakan via Babel (alat yang akan transpile JavaScript + fitur baru ke JavaScript lama biasa), dengan transform-async-to-generator plugin. Menjalankan

npm install babel-cli --save

Membuat .babelrc dengan:

{
  "plugins": [
    "transform-async-to-generator",
  ]
}

Kemudian jalankan kode Anda dengan

node_modules/babel-cli/bin/babel-node.js sleep.js

Tetapi sekali lagi, Anda tidak memerlukan ini jika Anda menggunakan Node 7 atau lebih baru, atau jika Anda menargetkan peramban modern.


1071



(Lihat jawaban terupdate untuk 2016)

Saya pikir sangat masuk akal untuk ingin melakukan tindakan, menunggu, lalu melakukan tindakan lain. Jika Anda terbiasa menulis dalam bahasa multi-berulir, Anda mungkin memiliki gagasan menghasilkan eksekusi untuk jumlah waktu yang ditetapkan sampai thread Anda bangun.

Masalahnya di sini adalah bahwa JavaScript adalah model berbasis kejadian single-thread. Sementara dalam kasus tertentu, mungkin menyenangkan untuk memiliki seluruh mesin menunggu selama beberapa detik, pada umumnya itu adalah praktik yang buruk. Seandainya saya ingin menggunakan fungsi Anda saat menulis sendiri? Ketika saya menelepon metode Anda, metode saya semua akan membeku. Jika JavaScript entah bagaimana bisa mempertahankan konteks eksekusi fungsi Anda, menyimpannya di suatu tempat, lalu membawanya kembali dan melanjutkannya nanti, maka tidur bisa terjadi, tetapi itu pada dasarnya akan menjadi threading.

Jadi Anda cukup banyak terjebak dengan apa yang orang lain sarankan - Anda harus memecah kode Anda menjadi beberapa fungsi.

Pertanyaan Anda adalah sedikit pilihan yang salah, lalu. Tidak ada cara untuk tidur dengan cara yang Anda inginkan, atau sebaiknya Anda mencari solusi yang Anda sarankan.


830



Dalam JavaScript, saya menulis ulang setiap fungsi sehingga dapat berakhir secepat mungkin. Anda ingin browser kembali memegang kendali sehingga dapat membuat perubahan DOM Anda.

Setiap kali saya ingin tidur di tengah-tengah fungsi saya, saya refactored untuk menggunakan setTimeout().

Saya akan mengedit jawaban ini karena saya menganggap ini berguna:

Tidur yang terkenal, atau penundaan, berfungsi dalam bahasa apa pun banyak diperdebatkan. Beberapa orang akan mengatakan bahwa harus selalu ada sinyal atau panggilan balik untuk memecat fungsi yang diberikan, yang lain akan berpendapat bahwa kadang-kadang penundaan waktu yang sewenang-wenang berguna. Saya mengatakannya kepada masing-masing mereka sendiri dan satu aturan tidak pernah dapat mendikte apa pun dalam industri ini.

Menulis fungsi tidur sederhana dan bahkan lebih bermanfaat dengan Janji JavaScript:

// sleep time expects milliseconds
function sleep (time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}

// Usage!
sleep(500).then(() => {
    // Do something after the sleep!
});

590



Hanya untuk debug / dev , Saya posting ini jika itu berguna untuk seseorang

Hal-hal yang menarik, di Firebug (& mungkin konsol js lainnya), tidak ada yang terjadi setelah menekan enter, hanya setelah durasi tidur yang ditentukan (...)

function sleepFor( sleepDuration ){
    var now = new Date().getTime();
    while(new Date().getTime() < now + sleepDuration){ /* do nothing */ } 
}

Contoh penggunaan:

function sleepThenAct(){ sleepFor(2000); console.log("hello js sleep !"); }

269



Saya setuju dengan poster lainnya, tidur yang sibuk adalah ide yang buruk.

Namun, setTimeout tidak menahan eksekusi, ia menjalankan baris fungsi berikutnya segera setelah batas waktu SET, bukan setelah batas waktu berakhir, sehingga tidak menyelesaikan tugas yang sama yang akan dicapai oleh tidur.

Cara melakukannya adalah menguraikan fungsi Anda ke sebelum dan sesudah bagian.

function doStuff()
{
  //do some things
  setTimeout(continueExecution, 10000) //wait ten seconds before continuing
}

function continueExecution()
{
   //finish doing things after the pause
}

Pastikan nama-nama fungsi Anda masih secara akurat menggambarkan apa yang dilakukan setiap bagian (I.E. 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 kembali ke PC klien untuk menjalankan apa pun yang telah diantrekan.

Sunting Lebih Lanjut

Seperti yang ditunjukkan di komentar ini benar-benar TIDAK BEKERJA dalam satu lingkaran. Anda dapat melakukan beberapa peretasan (jelek) untuk membuatnya bekerja dalam satu lingkaran, tetapi secara umum itu hanya akan membuat kode spageti bencana.


164



Untuk cinta DEITY, tolong jangan membuat fungsi tidur yang sibuk-tunggu. setTimeout dan setInterval lakukan semua yang kamu butuhkan.


113



Saya tahu ini adalah sedikit pertanyaan lama, tetapi jika (seperti saya) Anda menggunakan Javascript dengan Rhino, Anda dapat menggunakan ...

try
{
  java.lang.Thread.sleep(timeInMilliseconds);
}
catch (e)
{
  /*
   * This will happen if the sleep is woken up - you might want to check
   * if enough time has passed and sleep again if not - depending on how
   * important the sleep time is to you.
   */
}

109



Jika Anda menggunakan jQuery, seseorang benar-benar membuat plugin "delay" yang tidak lebih dari pembungkus untuk setTimeout:

// Delay Plugin for jQuery
// - http://www.evanbot.com
// -  2008 Evan Byrne

jQuery.fn.delay = function(time,func){
    this.each(function(){
        setTimeout(func,time);
    });

    return this;
};

Anda kemudian dapat menggunakannya dalam deretan panggilan fungsi seperti yang diharapkan:

$('#warning')
.addClass('highlight')
.delay(1000)
.removeClass('highlight');

65



Saya sudah mencari solusi tidur juga (tidak 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/

Juga, saat Anda menelepon alert(), kode Anda akan dijeda juga, sementara peringatan ditampilkan - perlu menemukan cara untuk tidak menampilkan peringatan tetapi mendapatkan efek yang sama. :)


42



Di sini kamu pergi. Seperti kata kode, jangan menjadi pengembang yang buruk dan gunakan ini di situs web. Ini adalah fungsi utilitas pengembangan.

// Basic sleep function based on ms.
// DO NOT USE ON PUBLIC FACING WEBSITES.
function sleep(ms) {
    var unixtime_ms = new Date().getTime();
    while(new Date().getTime() < unixtime_ms + ms) {}
}

28