Cách đặt thời gian trễ trong javascript


170

Tôi có một đoạn js trong trang web của mình để chuyển đổi hình ảnh nhưng cần độ trễ khi bạn nhấp vào hình ảnh lần thứ hai. Độ trễ phải là 1000ms. Vì vậy, bạn sẽ nhấp vào img.jpg sau đó img_onclick.jpg sẽ xuất hiện. Sau đó, bạn sẽ nhấp vào hình ảnh img_onclick.jpg sau đó sẽ có độ trễ 1000ms trước khi img.jpg được hiển thị lại.

Đây là mã:

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();
    });
});

8
setTimeout(function(){/*YourCode*/},1000);
marteljn


có thể tìm kiếm .stop()mặc dù. Hãy xem tại đây api.jquery.com/stop
Mark Walters

Bản sao có thể có của Đặt độ trễ trong Javascript
Ẩn danh

Câu trả lời:


380

Sử dụng setTimeout():

var delayInMilliseconds = 1000; //1 second

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

Nếu bạn muốn làm điều đó mà không có setTimeout: Tham khảo câu hỏi này .


6
Làm thế nào để làm điều đó một cách đồng bộ? mã bên trong setTimeout không nhận ra thuộc tính lớp.
ishandutta2007

@ ishandutta2007 xem câu trả lời của tôi dưới đây -> stackoverflow.com/a/49813472/3919057
Ninjaneer

50
setTimeout(function(){


}, 500); 

Đặt mã của bạn bên trong { }

500 = 0,5 giây

2200 = 2,2 giây

Vân vân.


18

Giải pháp ES-6

Dưới đây là mã mẫu sử dụng aync / await để có độ trễ thực tế.

Có nhiều ràng buộc và điều này có thể không hữu ích, nhưng chỉ đăng ở đây cho vui ..

    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();


3
Nó là không cần thiết cho delaychức năng là không đồng bộ. Sự trì hoãn tuyệt vời này hoạt động khi một Lời hứa được trả về bởi một chức năng thông thường được chờ đợi trong phần thân của chức năng không đồng bộ.
Intervoice

13

Có hai loại (hầu hết được sử dụng) chức năng hẹn giờ trong javascript setTimeoutsetInterval( loại khác )

Cả hai phương pháp này đều có cùng chữ ký. Họ lấy chức năng gọi lại và trì hoãn thời gian làm tham số.

setTimeoutchỉ thực hiện một lần sau khi trì hoãn trong khi setIntervaltiếp tục gọi hàm gọi lại sau mỗi milisec trễ.

cả hai phương thức này đều trả về một định danh số nguyên có thể được sử dụng để xóa chúng trước khi hết giờ.

clearTimeoutclearIntervalcả hai phương thức này đều nhận một số nhận dạng nguyên được trả về từ các hàm trên setTimeoutsetInterval

Thí dụ:

setTimeout

alert("before setTimeout");

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

  alert("after setTimeout");

Nếu bạn chạy đoạn mã trên, bạn sẽ thấy nó cảnh báo before setTimeoutafter setTimeoutcuối cùng nó sẽ cảnh báo I am setTimeoutsau 1 giây (1000ms)

Những gì bạn có thể nhận thấy từ ví dụ là setTimeout(...)không đồng bộ, điều đó có nghĩa là nó không đợi bộ đếm thời gian bị trôi qua trước khi đi đến câu lệnh tiếp theo, tức làalert("after setTimeout");

Thí dụ:

xác định

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);

Nếu bạn chạy mã ở trên, bạn sẽ thấy nó cảnh báo before setIntervalafter setIntervalcuối cùng nó sẽ cảnh báo I am setInterval 5 lần sau 1 giây (1000ms) vì setTimeout xóa bộ hẹn giờ sau 5 giây hoặc cứ sau 1 giây bạn sẽ nhận được cảnh báo I am setIntervalVô hạn.

Làm thế nào trình duyệt nội bộ làm điều đó?

Tôi sẽ giải thích ngắn gọn.

Để hiểu rằng bạn phải biết về hàng đợi sự kiện trong javascript. Có một hàng đợi sự kiện được thực hiện trong trình duyệt. Bất cứ khi nào một sự kiện được kích hoạt trong js, tất cả các sự kiện này (như nhấp chuột, v.v.) sẽ được thêm vào hàng đợi này. Khi trình duyệt của bạn không có gì để thực thi, nó sẽ lấy một sự kiện từ hàng đợi và thực thi từng cái một.

Bây giờ, khi bạn gọi setTimeouthoặc setIntervalcuộc gọi lại của bạn được đăng ký vào một bộ đếm thời gian trong trình duyệt và nó được thêm vào hàng đợi sự kiện sau khi hết thời gian nhất định và cuối cùng javascript lấy sự kiện từ hàng đợi và thực thi nó.

Điều này xảy ra như vậy, bởi vì công cụ javascript là một luồng và chúng chỉ có thể thực thi một điều duy nhất tại một thời điểm. Vì vậy, họ không thể thực thi các javascript khác và theo dõi bộ đếm thời gian của bạn. Đó là lý do tại sao các bộ hẹn giờ này được đăng ký với trình duyệt (trình duyệt không phải là một luồng) và nó có thể theo dõi bộ đếm thời gian và thêm một sự kiện trong hàng đợi sau khi hết giờ.

điều tương tự chỉ xảy ra setIntervaltrong trường hợp này, sự kiện được thêm vào hàng đợi một lần nữa sau khoảng thời gian được chỉ định cho đến khi nó bị xóa hoặc làm mới trang trình duyệt.

Ghi chú

Tham số độ trễ bạn chuyển đến các hàm này là thời gian trễ tối thiểu để thực hiện gọi lại. Điều này là do sau khi hết giờ, trình duyệt thêm sự kiện vào hàng đợi để được thực thi bởi công cụ javascript nhưng việc thực hiện cuộc gọi lại phụ thuộc vào vị trí sự kiện của bạn trong hàng đợi và vì công cụ là một luồng, nó sẽ thực hiện tất cả các sự kiện trong hàng đợi từng người một.

Do đó, cuộc gọi lại của bạn đôi khi có thể mất nhiều thời gian hơn thời gian trì hoãn được chỉ định để được gọi đặc biệt khi mã khác của bạn chặn luồng và không cho nó thời gian để xử lý những gì có trong hàng đợi.

Và như tôi đã đề cập javascript là một chủ đề duy nhất. Vì vậy, nếu bạn chặn các chủ đề trong thời gian dài.

Thích mã này

while(true) { //infinite loop 
}

Người dùng của bạn có thể nhận được một trang thông báo không phản hồi .


1
Bạn có thể cho tôi biết làm thế nào tôi có thể dừng hành vi không đồng bộ của setTimeout () không?
Chandan Purbia

Bạn không sử dụng setTimeoutnếu bạn không muốn hành vi không đồng bộ.
Nadir Laskar

5

Đối với các cuộc gọi đồng bộ, bạn có thể sử dụng phương thức bên dưới:

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

0

Nếu bạn cần làm mới, đây là một khả năng khác:

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

0

Đây là những gì tôi đang làm để giải quyết vấn đề này. Tôi đồng ý điều này là do vấn đề thời gian và cần tạm dừng để thực thi mã.

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

Mã mới này sẽ tạm dừng nó trong 1 giây và trong khi đó chạy mã của bạn.


0

Tôi sẽ cung cấp đầu vào của tôi vì nó giúp tôi hiểu những gì tôi đang làm.

Để tạo một trình chiếu cuộn tự động có thời gian chờ 3 giây, tôi đã làm như sau:

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);

Hãy nhớ rằng khi thực hiện setTimeout () như thế này; nó sẽ thực thi tất cả các hàm hết thời gian như thể chúng thực hiện cùng lúc với giả định rằng trong setTimeout (nextImage, delayTime); thời gian trễ là 3000 mili giây tĩnh.

Những gì tôi đã làm để giải thích cho điều này là thêm 3000 mili / giây sau mỗi lần tăng vòng lặp thông qua delayTime += timeIncrement;.

Đối với những người quan tâm ở đây là nextImage () của tôi trông như thế nào:

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;
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.