【问题标题】:how to make a sleep in javascript?如何在javascript中睡觉?
【发布时间】:2009-06-24 06:00:02
【问题描述】:

有谁知道如何在系统读取下一行之前在 javascript 中休眠?

示例:

    1 var chkResult = Validation();
    2 //sleep here for for 10 sec before the next line been read    
    3   
    4 document.getElementById('abc').innerHTML = chkResult;

对于这个例子,如何让 javascript 在第 2 行休眠/等待 10 秒,然后继续读取第 4 行?我试过 setTimeout('', 10000);但它似乎对我仍然不起作用......

【问题讨论】:

  • 在 javascript 中休眠是个坏主意,因为它会导致浏览器的 UI 变得无响应
  • 我担心进行十秒钟的验证。是服务器响应的时间吗?如果您使用 ajax 调用进行验证,您不应该收到回调吗?

标签: javascript jquery ajax


【解决方案1】:

I Have the Hat 给出了正确的提示。使用setTimeout method 在 10 秒后执行您的第四行代码:

var chkResult = Validation();
var timeout = window.setTimeout(function() {
    document.getElementById('abc').innerHTML = chkResult;
}, 10000);

如果您想clear a timeout,将超时 ID 存储在变量中会很方便。

【讨论】:

    【解决方案2】:

    试试

    setTimeout(function() { return true; }, 10000);
    

    第一个参数需要一个函数。这是凭记忆的;我没有测试过。

    编辑: Gumbo 说的……迟到了……不知道我在想什么。

    【讨论】:

    【解决方案3】:
        1 var chkResult = Validation();
        2 alert("wait ten seconds, then press ok");
        3       
        4 document.getElementById('abc').innerHTML = chkResult;
    

    前面的代码将睡眠任务委托给并行处理器。这有点混乱,因为您必须使用 DSL 来处理这种类型的线程。

    【讨论】:

      【解决方案4】:

      setTimeout 在 JavaScript 解释器中启动一个单独的执行“线程”。您需要向它传递一个函数并设计您的脚本,以使 setTimeout 运行的函数将在调用函数停止的地方继续 - 从而模拟睡眠。

      【讨论】:

        【解决方案5】:

        在 JavaScript 将控制权交还给浏览器之前不会发生延迟,因此您的第 4 行将在 setTimeout 开始之前执行。

        你应该根据事件来让一切发生。

        【讨论】:

          【解决方案6】:

          我可以建议将此作为通用解决方案吗:

            function sleep (ms, args, obj) {
              /* Called at the top of a function to invoke a delay in processing that
                 function
          
                 Returns true if the function should be executed, and false if the sleep
                 timer is activated. 
          
                 At the end of the sleep tiemout, the calling function is re-called by
                 calling it with "apply (obj, args || [])".
              */
          
              var caller = sleep.caller;
              if (caller.sleepTimer) { 
                /* if invoked from timeout function, delete timer and return false */
                delete caller.sleepTimer;
                return true;
              }
          
              /* Create timer and re-call caller at expiry */
              caller.sleepTimer = window.setTimeout (function () {
                caller.apply (obj || null, args || []);
              },ms);
          
              return false;
            }    
          

          使用示例:

          function delayed () {
            if (!sleep (5000)) return;  
          
            document.body.innerHTML += "<p>delayed processing</p>";
          }
          
          function delayed_args (a, b) {
            if (!sleep (10000, arguments)) return;  
          
            document.body.innerHTML += "<p>args : (" + a + ", " + b + ")</p>";
          }
          
          function delayed_method_args (a,b) {
            if (!sleep (20000, arguments, this)) return;  
          
            document.body.innerHTML += "<p>method_args " + this + " (" + a + ", " + b + ")</p>";
          }
          

          在 Opera 和 Firefox 3.0 上测试

          【讨论】:

            【解决方案7】:

            Javascript 必须与浏览器共享线程,所以你想要的那种暂停看起来很像浏览器被冻结了 10 秒,如果可能的话。诸如“警报”和“提示”之类的功能就是这样做的。为此,它们是邪恶的,因为循环中的单个警报可能会使整个浏览器瘫痪,唯一的出路就是强制退出。

            解决这个问题的方法是基于事件的范例。 Javascript 具有一流的函数,因此它们可以作为“回调”的值传递,您可以将其分配给某些事件。

            setTimeout 就是这样一个事件。其他人已经发布了代码,但一般来说,您只想将您的功能分配给某些事件,然后避开浏览器,以便它可以进行浏览器业务。浏览器会在发生某些事情时通知您,您可以快速做出适当的响应,然后再次让开。这样,浏览器就可以保持响应式的外观。

            如果您想了解更多信息,请查看以下问题: How is GUI and Game Program Flow compared to Web programs

            【讨论】:

              【解决方案8】:

              但是这样一来,您的 line line 将在 line 4 之前执行

              【讨论】:

                【解决方案9】:

                JS中没有睡眠功能。

                但是,您可以使用 setTimeout:

                var chkResult = Validation();
                setTimeout(() => { document.getElementById('abc').innerHTML = chkResult }, 10000);
                

                更现代的方法是使用 Promise 和异步函数:

                const doThis = () => document.querySelectorAll('p')[0].innerHTML ='Do this';
                const doThat = () => document.querySelectorAll('p')[1].innerHTML ='Do that';
                const doAlsoThat = () => document.querySelectorAll('p')[2].innerHTML ='Do also that';
                const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
                
                // using async function
                (async () => {
                  doThis(); // executed at t=0s (approx)
                  await sleep(1000);
                  doThat(); // executed at t=1s (approx)
                })();
                
                // using promises
                sleep(2000).then(doAlsoThat); // executed at t=2s (approx)
                <p></p>
                <p></p>
                <p></p>

                【讨论】:

                  猜你喜欢
                  • 2011-09-22
                  • 2012-11-03
                  • 2011-10-19
                  • 2021-10-11
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-05-17
                  • 2012-06-27
                  相关资源
                  最近更新 更多