วิธีการตั้งค่าหน่วงเวลาใน javascript


170

ฉันมี js ชิ้นนี้ในเว็บไซต์ของฉันเพื่อสลับภาพ แต่ต้องการความล่าช้าเมื่อคุณคลิกที่ภาพเป็นครั้งที่สอง ความล่าช้าควรเป็น 1000ms ดังนั้นคุณจะคลิก img.jpg จากนั้น img_onclick.jpg จะปรากฏขึ้น จากนั้นคุณจะคลิกที่ภาพ img_onclick.jpg ซึ่งจะมีความล่าช้า 1,000ms ก่อนที่จะปรากฏ img.jpg อีกครั้ง

นี่คือรหัส:

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


อาจมองหา.stop()ว่า ดูที่นี่api.jquery.com/stop
Mark Walters

ซ้ำซ้อนที่อาจเป็นไปได้ใน Javascript
ไม่ระบุชื่อ

คำตอบ:


380

การใช้setTimeout():

var delayInMilliseconds = 1000; //1 second

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

หากคุณต้องการที่จะทำโดยไม่setTimeout: อ้างอิงคำถามนี้


6
วิธีการทำมันซิงโครนัส? รหัสภายใน setTimeout ไม่รู้จักคุณสมบัติคลาส
ishandutta2007

@ ishandutta2007 ดูคำตอบของฉันด้านล่าง -> stackoverflow.com/a/49813472/3919057
Ninjaneer

50
setTimeout(function(){


}, 500); 

วางรหัสของคุณใน { }

500 = 0.5 วินาที

2200 = 2.2 วินาที

เป็นต้น


18

โซลูชัน ES-6

ด้านล่างนี้คือตัวอย่างรหัสที่ใช้aync / ที่รอการหน่วงเวลาจริง

มีข้อ จำกัด มากมายและอาจไม่เป็นประโยชน์ แต่เพียงโพสต์ที่นี่เพื่อความสนุกสนาน ..

    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
มันไม่จำเป็นสำหรับdelayฟังก์ชั่นที่จะ async การหน่วงเวลาที่ยอดเยี่ยมนี้ทำงานเมื่อสัญญาที่ส่งคืนโดยฟังก์ชันปกติกำลังรออยู่ในเนื้อความของฟังก์ชัน async
วอยซ์

13

มีฟังก์ชันตัวจับเวลาสองประเภท (ส่วนใหญ่ใช้) ในจาวาสคริปต์setTimeoutและsetInterval( อื่น ๆ )

ทั้งสองวิธีนี้มีลายเซ็นเหมือนกัน พวกเขาใช้ฟังก์ชั่นโทรกลับและเวลาล่าช้าเป็นพารามิเตอร์

setTimeoutดำเนินการเพียงครั้งเดียวหลังจากที่ล่าช้าในขณะที่setIntervalยังคงโทรฟังก์ชั่นการโทรกลับหลังจาก milisecs ล่าช้าทุกครั้ง

ทั้งวิธีการเหล่านี้จะส่งกลับตัวระบุจำนวนเต็มที่สามารถใช้ในการล้างพวกเขาก่อนที่ตัวจับเวลาจะหมดอายุ

clearTimeoutและclearIntervalทั้งสองวิธีนี้ใช้ตัวระบุจำนวนเต็มซึ่งส่งคืนจากฟังก์ชันด้านบนsetTimeoutและsetInterval

ตัวอย่าง:

setTimeout

alert("before setTimeout");

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

  alert("after setTimeout");

หากคุณเรียกใช้รหัสข้างต้นคุณจะเห็นว่ามันแจ้งเตือนbefore setTimeoutแล้วafter setTimeoutในที่สุดก็แจ้งเตือนI am setTimeoutหลังจาก 1 วินาที (1000ms)

สิ่งที่คุณสามารถสังเกตได้จากตัวอย่างคือsetTimeout(...)อะซิงโครนัสซึ่งหมายความว่ามันไม่รอให้ตัวจับเวลาผ่านไปก่อนที่จะไปยังคำสั่งถัดไปเช่นalert("after setTimeout");

ตัวอย่าง:

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

หากคุณเรียกใช้รหัสข้างต้นคุณจะเห็นว่ามันแจ้งเตือนbefore setIntervalแล้วafter setIntervalในที่สุดก็แจ้งเตือนI am setInterval 5 ครั้งหลังจาก 1sec (1000ms) เพราะ setTimeout ล้างจับเวลาหลังจาก 5 วินาทีหรืออื่น ๆ ทุก 1 วินาทีคุณจะได้รับการแจ้งเตือนอย่างI am setIntervalไม่มีที่สิ้นสุด

เบราว์เซอร์ทำหน้าที่อย่างไรภายใน

ฉันจะอธิบายโดยย่อ

เพื่อให้เข้าใจว่าคุณต้องรู้เกี่ยวกับคิวเหตุการณ์ในจาวาสคริปต์ มีคิวเหตุการณ์ที่ใช้ในเบราว์เซอร์ เมื่อใดก็ตามที่เหตุการณ์ถูกเรียกใน js เหตุการณ์เหล่านี้ทั้งหมด (เช่นคลิก ฯลฯ .. ) จะถูกเพิ่มในคิวนี้ เมื่อเบราว์เซอร์ของคุณไม่มีอะไรดำเนินการก็จะใช้กิจกรรมจากคิวและดำเนินการทีละรายการ

ตอนนี้เมื่อคุณโทรsetTimeoutหรือsetIntervalโทรกลับของคุณได้รับการลงทะเบียนกับตัวจับเวลาในเบราว์เซอร์และมันจะถูกเพิ่มเข้าไปในคิวเหตุการณ์หลังจากเวลาที่กำหนดหมดอายุลงและในที่สุด javascript จะใช้เหตุการณ์จากคิวและดำเนินการ

สิ่งนี้เกิดขึ้นเนื่องจากเครื่องมือจาวาสคริปต์เป็นเธรดเดี่ยวและสามารถดำเนินการได้ครั้งละหนึ่งสิ่งเท่านั้น ดังนั้นจึงไม่สามารถเรียกใช้ javascript อื่น ๆ และติดตามการจับเวลาของคุณได้ นั่นคือเหตุผลที่ตัวจับเวลาเหล่านี้ลงทะเบียนกับเบราว์เซอร์ (เบราว์เซอร์ไม่ใช่เธรดเดี่ยว) และสามารถติดตามตัวจับเวลาและเพิ่มเหตุการณ์ในคิวหลังจากตัวจับเวลาหมดอายุ

จะเกิดขึ้นเช่นกันsetIntervalเฉพาะในกรณีนี้เหตุการณ์จะถูกเพิ่มในคิวอีกครั้งและอีกครั้งหลังจากช่วงเวลาที่ระบุจนกว่าจะได้รับการล้างหรือหน้าเบราว์เซอร์รีเฟรช

บันทึก

พารามิเตอร์การหน่วงเวลาที่คุณส่งไปยังฟังก์ชั่นเหล่านี้คือเวลาหน่วงขั้นต่ำที่จะดำเนินการติดต่อกลับ นี่เป็นเพราะหลังจากตัวจับเวลาหมดอายุเบราว์เซอร์จะเพิ่มเหตุการณ์ในคิวที่จะดำเนินการโดยโปรแกรมจาวาสคริปต์ แต่การดำเนินการโทรกลับขึ้นอยู่กับตำแหน่งกิจกรรมของคุณในคิวและเนื่องจากเอ็นจิ้นเป็นเธรดเดียว คิวหนึ่งโดยหนึ่ง

ดังนั้นการโทรกลับของคุณอาจใช้เวลานานกว่าเวลาหน่วงที่ระบุเพื่อเรียกเป็นพิเศษเมื่อโค้ดอื่น ๆ ของคุณบล็อกเธรดและไม่ให้เวลาในการประมวลผลสิ่งที่อยู่ในคิว

และอย่างที่ฉันได้กล่าวถึงจาวาสคริปต์คือเธรดเดียว ดังนั้นหากคุณบล็อกเธรดเป็นเวลานาน

ชอบรหัสนี้

while(true) { //infinite loop 
}

ผู้ใช้ของคุณอาจได้รับข้อความว่าหน้าไม่ตอบสนอง


1
คุณช่วยบอกฉันได้ฉันจะหยุดพฤติกรรมอะซิงโครนัสของ setTimeout () ได้อย่างไร
Chandan Purbia

คุณไม่ได้ใช้setTimeoutถ้าคุณไม่ต้องการพฤติกรรมแบบอะซิงโครนัส
ขีดตกต่ำสุดของ Laskar

5

สำหรับการโทรแบบซิงค์คุณสามารถใช้วิธีการด้านล่าง:

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

0

หากคุณต้องการรีเฟรชนี่คือความเป็นไปได้อีกอย่าง:

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

0

นี่คือสิ่งที่ฉันกำลังทำเพื่อแก้ไขปัญหานี้ ฉันเห็นด้วยนี้เป็นเพราะปัญหาเวลาและต้องการหยุดชั่วคราวเพื่อรันโค้ด

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

รหัสใหม่นี้จะหยุดชั่วคราวเป็นเวลา 1 วินาทีและในขณะเดียวกันก็รันรหัสของคุณ


0

ฉันจะให้ข้อมูลของฉันเพราะมันช่วยให้ฉันเข้าใจสิ่งที่ฉันทำ

หากต้องการสร้างการนำเสนอภาพนิ่งแบบเลื่อนอัตโนมัติที่ใช้เวลา 3 วินาทีฉันได้ทำสิ่งต่อไปนี้:

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

โปรดจำไว้ว่าเมื่อดำเนินการ setTimeout () เช่นนี้ มันจะดำเนินการฟังก์ชั่นหมดเวลาราวกับว่าพวกเขาที่ดำเนินการในเวลาเดียวกันสมมติว่าใน setTimeout (nextImage, delayTime) เวลาล่าช้าเป็นแบบคงที่ 3000 มิลลิวินาที

สิ่งที่ฉันได้ไปยังบัญชีสำหรับการนี้ก็เพิ่มพิเศษ 3000 หนึ่งในพัน / s หลังจากแต่ละสำหรับวง incrementation delayTime += timeIncrement;ผ่าน

สำหรับผู้ที่สนใจนี่คือสิ่งที่ nextImage () ของฉันดูเหมือน:

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;
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.