Cara mengatur waktu tunda dalam javascript

170

Saya punya ini js di situs web saya untuk beralih gambar tetapi perlu penundaan ketika Anda mengklik gambar untuk kedua kalinya. Penundaan harus 1000 ms. Jadi Anda akan mengklik img.jpg maka img_onclick.jpg akan muncul. Anda kemudian akan mengklik gambar img_onclick.jpg maka harus ada penundaan 1000 ms sebelum img.jpg ditampilkan lagi.

Ini kodenya:

jQuery(document).ready(function($) {

    $(".toggle-container").hide();
    $(".trigger").toggle(function () {
        $(this).addClass("active");
        $(".trigger").find('img').prop('src', 'http://localhost:8888/images/img_onclick.jpg');
    }, function () {
        $(this).removeClass("active");
        $(".trigger").find('img').prop('src', 'http://localhost:8888/images/img.jpg');
    });
    $(".trigger").click(function () {
        $(this).next(".toggle-container").slideToggle();
    });
});
Oranye biru
sumber
8
setTimeout(function(){/*YourCode*/},1000);
marteljn
mungkin mencari .stop()sekalipun. Silakan
Mark Walters
Kemungkinan rangkap dari Put a Delay in Javascript
Anonymous

Jawaban:

380

Gunakan setTimeout():

var delayInMilliseconds = 1000; //1 second

setTimeout(function() {
  //your code to be executed after 1 second
}, delayInMilliseconds);

Jika Anda ingin melakukannya tanpa setTimeout: Lihat pertanyaan ini .

THIRUR HIRA
sumber
6
bagaimana cara melakukannya secara sinkron? kode di dalam setTimeout tidak mengenali properti kelas.
ishandutta2007
@ ishandutta2007 lihat jawaban saya di bawah -> stackoverflow.com/a/49813472/3919057
Ninjaneer
50
setTimeout(function(){


}, 500); 

Tempatkan kode Anda di dalam { }

500 = 0,5 detik

2200 = 2,2 detik

dll.

maudulus
sumber
18

Solusi ES-6

Di bawah ini adalah contoh kode yang menggunakan aync / menunggu untuk memiliki penundaan yang sebenarnya.

Ada banyak kendala dan ini mungkin tidak berguna, tetapi hanya memposting di sini untuk bersenang-senang ..

    async function delay(delayInms) {
      return new Promise(resolve  => {
        setTimeout(() => {
          resolve(2);
        }, delayInms);
      });
    }
    async function sample() {
      console.log('a');
      console.log('waiting...')
      let delayres = await delay(3000);
      console.log('b');
    }
    sample();

Ninjaneer
sumber
3
TIDAK perlu delayfungsi menjadi async. Keterlambatan yang luar biasa ini berfungsi ketika Janji yang dikembalikan oleh fungsi reguler ditunggu di tubuh fungsi async.
Intervoice
13

Ada dua jenis fungsi penghitung waktu (kebanyakan digunakan) dalam javascript setTimeoutdan setInterval( lainnya )

Kedua metode ini memiliki tanda tangan yang sama. Mereka mengambil fungsi panggilan balik dan menunda waktu sebagai parameter.

setTimeoutdieksekusi hanya sekali setelah penundaan sedangkan setIntervalterus memanggil fungsi callback setelah setiap penundaan milidetik.

kedua metode ini mengembalikan pengenal bilangan bulat yang dapat digunakan untuk menghapusnya sebelum timer kedaluwarsa.

clearTimeoutdan clearIntervalkedua metode ini mengambil pengenal integer yang dikembalikan dari fungsi di atas setTimeoutdansetInterval

Contoh:

setTimeout

alert("before setTimeout");

setTimeout(function(){
        alert("I am setTimeout");
   },1000); //delay is in milliseconds 

  alert("after setTimeout");

Jika Anda menjalankan kode di atas, Anda akan melihat bahwa itu mengingatkan before setTimeoutdan after setTimeoutakhirnya mengingatkan I am setTimeoutsetelah 1sec (1000 ms)

Apa yang dapat Anda perhatikan dari contoh adalah bahwa setTimeout(...)asynchronous yang berarti tidak menunggu timer untuk berlalu sebelum pergi ke pernyataan berikutnya yaitualert("after setTimeout");

Contoh:

setInterval

alert("before setInterval"); //called first

 var tid = setInterval(function(){
        //called 5 times each time after one second  
      //before getting cleared by below timeout. 
        alert("I am setInterval");
   },1000); //delay is in milliseconds 

  alert("after setInterval"); //called second

setTimeout(function(){
     clearInterval(tid); //clear above interval after 5 seconds
},5000);

Jika Anda menjalankan kode di atas, Anda akan melihat bahwa itu mengingatkan before setIntervaldan after setIntervalakhirnya memberitahu I am setInterval 5 kali setelah 1sec (1000 ms) karena setTimeout menghapus timer setelah 5 detik atau setiap 1 detik Anda akan mendapatkan peringatan tak I am setIntervalterhingga.

Bagaimana browser secara internal melakukannya?

Saya akan jelaskan secara singkat.

Untuk memahami bahwa Anda harus tahu tentang antrian acara dalam javascript. Ada antrian acara yang diterapkan di browser. Setiap kali suatu peristiwa dipicu dalam js, semua peristiwa ini (seperti klik dll.) Ditambahkan ke antrian ini. Ketika browser Anda tidak memiliki apa-apa untuk dieksekusi, dibutuhkan suatu acara dari antrian dan mengeksekusi mereka satu per satu.

Sekarang, ketika Anda menelepon setTimeoutatau setIntervalpanggilan balik Anda didaftarkan ke timer di browser dan itu akan ditambahkan ke antrian acara setelah waktu yang diberikan berakhir dan akhirnya javascript mengambil acara dari antrian dan menjalankannya.

Ini terjadi demikian, karena mesin javascript adalah utas tunggal dan mereka hanya dapat mengeksekusi satu hal pada satu waktu. Jadi, mereka tidak dapat mengeksekusi javascript lain dan melacak timer Anda. Itulah mengapa timer ini terdaftar dengan browser (browser tidak satu threaded) dan dapat melacak timer dan menambahkan acara dalam antrian setelah timer berakhir.

hal yang sama terjadi setIntervalhanya dalam kasus ini acara ditambahkan ke antrian lagi dan lagi setelah interval yang ditentukan sampai dibersihkan atau halaman browser di-refresh.

Catatan

Parameter penundaan yang Anda berikan ke fungsi-fungsi ini adalah waktu tunda minimum untuk menjalankan panggilan balik. Ini karena setelah penghitung waktu kedaluwarsa browser menambahkan acara ke antrian untuk dieksekusi oleh mesin javascript tetapi pelaksanaan panggilan balik tergantung pada posisi acara Anda dalam antrian dan karena mesin berulir tunggal, ia akan menjalankan semua peristiwa dalam antrian satu per satu.

Karenanya, panggilan balik Anda kadang-kadang membutuhkan waktu lebih dari waktu tunda yang ditentukan untuk dipanggil secara khusus ketika kode Anda yang lain memblokir utas dan tidak memberikan waktu untuk memproses apa yang ada dalam antrian.

Dan seperti yang saya sebutkan javascript adalah utas tunggal. Jadi, jika Anda memblokir utasnya lama.

Suka kode ini

while(true) { //infinite loop 
}

Pengguna Anda mungkin mendapatkan pesan yang mengatakan halaman tidak merespons .

Nadir Laskar
sumber
1
Bisakah Anda memberi tahu saya cara menghentikan perilaku asinkron setTimeout ()?
Chandan Purbia
Anda tidak menggunakan setTimeoutjika Anda tidak ingin perilaku asinkron.
Nadir Laskar
5

Untuk panggilan sinkronisasi, Anda dapat menggunakan metode di bawah ini:

function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}
pengguna1188867
sumber
0

Jika Anda perlu menyegarkan, ini adalah kemungkinan lain:

setTimeout(function () { 
    $("#jsSegurosProductos").jsGrid("refresh"); 
}, 1000);
oOJITOSo
sumber
0

Inilah yang saya lakukan untuk menyelesaikan masalah ini. Saya setuju ini karena masalah waktu dan perlu jeda untuk mengeksekusi kode.

var delayInMilliseconds = 1000; 
setTimeout(function() {
 //add your code here to execute
 }, delayInMilliseconds);

Kode baru ini akan menjeda selama 1 detik dan sementara itu jalankan kode Anda.

Amir Md Amiruzzaman
sumber
0

Saya akan memberikan masukan karena membantu saya memahami apa yang saya lakukan.

Untuk membuat tayangan slide gulir otomatis yang menunggu 3 detik, saya melakukan hal berikut:

var isPlaying = true;

function autoPlay(playing){
   var delayTime = 3000;
   var timeIncrement = 3000;

   if(playing){
        for(var i=0; i<6; i++){//I have 6 images
            setTimeout(nextImage, delayTime);
            delayTime += timeIncrement;
        }
        isPlaying = false;

   }else{
       alert("auto play off");
   }
}

autoPlay(isPlaying);

Ingat bahwa ketika menjalankan setTimeout () seperti ini; itu akan mengeksekusi semua fungsi time out seolah-olah mereka di mana dieksekusi pada saat yang sama dengan asumsi bahwa dalam setTimeout (nextImage, delayTime); waktu tunda adalah statis 3000 milidetik.

Apa yang saya lakukan untuk menjelaskan hal ini adalah menambah 3000 mili / s setelah masing-masing untuk penambahan loop melalui delayTime += timeIncrement;.

Bagi mereka yang peduli di sini adalah seperti apa nextImage () saya:

function nextImage(){
    if(currentImg === 1){//change to img 2
        for(var i=0; i<6; i++){
            images[i].style.zIndex = "0";
        }
        images[1].style.zIndex = "1";
        imgNumber.innerHTML = imageNumber_Text[1];
        imgDescription.innerHTML = imgDescText[1];

        currentImg = 2;
    }
    else if(currentImg === 2){//change to img 3
        for(var i=0; i<6; i++){
            images[i].style.zIndex = "0";
        }
        images[2].style.zIndex = "1";
        imgNumber.innerHTML = imageNumber_Text[2];
        imgDescription.innerHTML = imgDescText[2];

        currentImg = 3;
    }
    else if(currentImg === 3){//change to img 4
        for(var i=0; i<6; i++){
            images[i].style.zIndex = "0";
        }
        images[3].style.zIndex = "1";
        imgNumber.innerHTML = imageNumber_Text[3];
        imgDescription.innerHTML = imgDescText[3];

        currentImg = 4;
    }
    else if(currentImg === 4){//change to img 5
        for(var i=0; i<6; i++){
            images[i].style.zIndex = "0";
        }
        images[4].style.zIndex = "1";
        imgNumber.innerHTML = imageNumber_Text[4];
        imgDescription.innerHTML = imgDescText[4];

        currentImg = 5;
    }
    else if(currentImg === 5){//change to img 6
    for(var i=0; i<6; i++){
            images[i].style.zIndex = "0";
        }
        images[5].style.zIndex = "1";
        imgNumber.innerHTML = imageNumber_Text[5];
        imgDescription.innerHTML = imgDescText[5];

        currentImg = 6;
    }
    else if(currentImg === 6){//change to img 1
        for(var i=0; i<6; i++){
            images[i].style.zIndex = "0";
        }
        images[0].style.zIndex = "1";
        imgNumber.innerHTML = imageNumber_Text[0];
        imgDescription.innerHTML = imgDescText[0];

        currentImg = 1;
    }
}
noetix
sumber