繁体   English   中英

如何在javascript中设置时间延迟

[英]How to set time delay in javascript

我在我的网站上有一段 js 来切换图像,但是当您第二次单击图像时需要延迟。 延迟应为 1000 毫秒。 所以你会点击 img.jpg 然后 img_onclick.jpg 会出现。 然后单击 img_onclick.jpg 图像,在 img.jpg 再次显示之前应该有 1000 毫秒的延迟。

这是代码:

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

使用setTimeout()

var delayInMilliseconds = 1000; //1 second

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

如果您想在没有setTimeout的情况下执行此操作:请参阅此问题

setTimeout(function(){


}, 500); 

将您的代码放在{ }

500 = 0.5 秒

2200 = 2.2 秒

等等

ES-6 解决方案

下面是一个示例代码,它使用aync/await来产生实际延迟。

有很多限制,这可能没有用,但在这里发帖只是为了好玩..

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

你可以使用承诺

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

然后用这个方法

console.log("Hello");
sleep(2000).then(() => { console.log("World!"); });

或者

console.log("Hello");
await sleep(2000);
console.log("World!");

javascript setTimeoutsetInterval ( other ) 中有两种(最常用的)定时器函数

这两种方法都具有相同的签名。 他们将回调函数和延迟时间作为参数。

setTimeout在延迟后仅执行一次,而setInterval在每个延迟毫秒后继续调用回调函数。

这两种方法都返回一个整数标识符,可用于在计时器到期之前清除它们。

clearTimeoutclearInterval这两个方法都采用从上述函数setTimeoutsetInterval返回的整数标识符

例子:

设置超时

alert("before setTimeout");

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

  alert("after setTimeout");

如果您运行上面的代码,您将看到它before setTimeout发出警报,然后after setTimeout最后发出警报I am setTimeout after 1sec (1000ms)

您可以从该示例中注意到setTimeout(...)是异步的,这意味着它不会等待计时器在进入下一条语句之前结束,即alert("after setTimeout");

例子:

设置间隔

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在 1 秒(1000 毫秒)后 5 次,因为 setTimeout 在 5 秒后清除计时器,否则每 1 秒您会收到警报I am setInterval Infinitely。

浏览器内部如何做到这一点?

我将简要解释。

要了解您必须了解 javascript 中的事件队列。 在浏览器中实现了一个事件队列。 每当在 js 中触发事件时,所有这些事件(如 click 等)都会添加到此队列中。 当您的浏览器没有要执行的内容时,它会从队列中获取一个事件并一一执行。

现在,当您调用setTimeoutsetInterval时,您的回调将注册到浏览器中的计时器,并在给定时间到期后添加到事件队列中,最终 javascript 从队列中获取事件并执行它。

之所以发生这种情况,是因为 javascript 引擎是单线程的,它们一次只能执行一件事。 因此,他们无法执行其他 javascript 并跟踪您的计时器。 这就是为什么这些计时器在浏览器中注册(浏览器不是单线程的)并且它可以跟踪计时器并在计时器到期后将事件添加到队列中。

仅在这种情况下, setInterval也会发生同样的情况,事件会在指定的时间间隔后一次又一次地添加到队列中,直到它被清除或刷新浏览器页面。

笔记

您传递给这些函数的延迟参数是执行回调的最小延迟时间。 这是因为在计时器到期后,浏览器将事件添加到队列中以由 javascript 引擎执行,但回调的执行取决于您在队列中的事件位置,并且由于引擎是单线程的,它将执行所有事件一一排队。

因此,当您的其他代码阻塞线程并且没有给它时间处理队列中的内容时,您的回调有时可能需要超过指定的延迟时间才能被调用。

正如我提到的,javascript 是单线程的。 所以,如果你长时间阻塞线程。

喜欢这段代码

while(true) { //infinite loop 
}

您的用户可能会收到一条消息说页面没有响应

对于同步呼叫,您可以使用以下方法:

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

这是我为解决此问题所做的工作。 我同意这是因为时间问题,需要暂停来执行代码。

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

此新代码将暂停 1 秒,同时运行您的代码。

如果您需要刷新,这是另一种可能性:

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

我会给出我的意见,因为它可以帮助我理解我在做什么。

为了制作等待 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 毫秒,它将执行所有超时功能,就好像它们同时执行一样。

为了解决这个问题,我所做的是在每个 for 循环增量后通过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;
    }
}

常量延迟 = (delayInms) => new Promise(resolve => setTimeout(resolve, delayInms)); 等待延迟(100)

我不是 JS 领域的专家,但我使用 setTimeout() 和递归函数找到了解决此问题的方法,如下所示:

i=0; //you should set i as a global variable
function recFunc() {
    i++;
    if (i == 1) {
        //do job1
    } else if (i == 2) {
        //do job2
    } else if (i == 3) {
        //do job3
    }
    if (i < 3) { //we have 3 distinct jobs. so the condition is (j < 3)
        setTimeout(function () {
            recFunc();
        }, 2000); //replace 2000 with desired delay
    }
}
//
//
//
recfunc(); //start the process

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM