sleep() in Javascript
假设我出于某种奇怪的原因想在某个时间阻止JavaScript的执行,我该怎么做呢?JS中没有sleep()。请不要说doeawhile()循环,因为这很糟糕。我可以做一个window.showModalDialog并在模式对话框中放置一个window.close,设置时间非常短,这样用户就不会注意到对话框。这就像小睡一段时间,如果需要的话,我可以多次打电话给你。还有别的办法吗?
更详细地说,我的用例是HTML5 SQL数据库提供了AsyncAPI,但我想将其用于存储永远不会很大的Samll Web应用程序。所以不需要异步API,因为小存储上的查询将在客户端运行。所以我想用同步API编写一个ORM,这样开发人员可以更容易地使用它。要桥接这个异步到同步API,我需要睡眠之类的东西。
如何使用
1 2 3 4 5 6 7 8 9 10 | function go() { if (go.count < 4) { // logs 1, 2, 3 to firebug console at 1 second intervals console.log(go.count++); window.setTimeout(go, 1000); } } go.count = 1; go(); |
如果您需要在超时结束之前清除超时,可以选择捕获超时ID以与
注意,无论是
@RussCam是对的,你要找的是
它不会阻止它所在的块的执行,相反,它会在一个特定的间隔后调用其输入函数。举例来说:
1 2 3 4 5 6 7 8 9 10 11 12 | function illustration() { // start out doing some setup code alert("This part will run first"); // set up some code to be executed later, in 5 seconds (5000 milliseconds): setTimeout(function () { alert("This code will run last, after a 5 second delay") }, 5000); // This code will run after the timeout is set, but before its supplied function runs: alert("This will be the second of 3 alert messages to display"); } |
运行此功能时,您将看到三条警报消息,其延迟介于第二条和第三条之间:
澄清:问题是要在一定时间内完全停止脚本的执行,而不是延迟某些代码的执行,这些代码将是setTimeout或setInterval的任务。
sleep()的干净实现在JavaScript中是不可能的,也不可取。
setimout和setinterval不会像这里的一些人认为的那样停止脚本的执行。只是注册一个要推迟运行的函数。当超时/间隔等待时,脚本的其余部分将继续运行。
由于JavaScript的异步特性,唯一"阻止"任何代码执行的方法是非常难看的,绝对不推荐在循环运行一定时间后执行。因为JavaScript本身是在一个线程中运行的(我们这里不讨论WebWorkers API…)。这将停止任何JS代码的运行,直到循环结束。但那真是糟糕的风格…
如果你的程序没有sleep()之类的东西就不能工作,也许你应该重新考虑一下你的方法。
I can do a window.showModalDialog and put a window.close in the modal dialog with setTimeout of very small time
这是创造性的,但它只允许用户与模式对话框中的任何内容进行交互,并且只允许用户在打开的时间长度内进行交互。浏览器的其余部分仍然挂起,就好像您刚刚调用了一个残酷的
模式对话框在CPU周期上比较友好,在等待时间较长的情况下可以避免触发脚本执行时间监视器,但您必须平衡这一点,以防干扰闪烁的打开对话框,以及非通用浏览器支持,以及每个人都讨厌模式对话框的问题!
This will be like sleep for small time period and I can call this multiple time if needed. Is there some other way?
你到底想通过睡觉来达到什么目的?如果不返回事件循环或触发模式对话框,您将无法获得任何屏幕更新或用户交互,因此我看不到内联睡眠将为您做什么。你当然不能这样做动画。
在firefox中,你会得到python风格的生成器,它允许你使用
埃塔:
I want to write an ORM with sync api so that developers can use it more easily. To bridge this async to sync api, I need something like sleep.
对不起,一般情况下不能做。基本的javascript没有线程、协同例程或其他可以桥接同步和异步代码的基元。
Web SQL数据库规范依赖于调用结果处理函数(作为浏览器回调传递给
理论上,您可以打开modaldialog,在
这个答案可能有点烦人,但很简单。
由于javascript通常在多线程浏览器中运行,其中javascript可能占用多个线程,因此没有"全局休眠"的概念,就像在单线程程序中那样。
如果您想以任何合理的方式暂停一个操作,您可能需要考虑以下内容。
假设你想
1 2 3 4 5 | function foo(s) { var j = 1; var k = 1; sleep(s); // This would be nice right? window.alert("Sum is :" + (j+k)); } |
实际上变成:
1 2 3 4 5 6 | function foo(s) { var j = 1 ; var k = 1; setTimeout(s, function() { window.alert("Sum is :" + (j+k)); }); } |
当然,问题是,从程序的意义上讲,你可能想要
1 2 3 4 5 6 7 8 9 10 11 | function foo() { do stuff; pause(); do more stuff; return; } function bar() { foo(10); window.alert("I want this to happen only after foo()"); } |
问题是,使用setTimeout不能真正做到这一点,如上图所示。
但是,您可以执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | function foo(s, afterwards, afterparms) { var j = 1 ; var k = 1; setTimeout(s, function() { window.alert("Sum is :" + (j+k)); afterparms.parm1 = afterparms.parm1.toUpperCase(); afterwards(afterparms); }); } function bar() { foo(10, function() { window.alert("This will happen after window.alert"); }, { parm1: 'hello', parm2: 'world' } ); } |
请注意,以上只是向函数传递信息的一种方法,如果查找函数调用约定、变量参数等,您可以做一些非常酷的事情。
如果你按程序思考的话,这对程序来说很烦人。但是,关于JavaScript有两件事需要记住。它不是程序语言,也不是面向对象的语言。JavaScript是一种功能性语言,具有复杂的事件管理模型。所以你必须用这些术语来思考。
这也很有意义,因为典型的JavaScript机器是一个GUI(Web浏览器),按照设计,它不希望在处理某些东西时完全阻塞。想象一下,当一个页面在做某件事情时,你的浏览器完全锁定了,你会想扼杀对你这样做的程序员。
javascript代码应该具有"失火和遗忘"的性质,如果在继续之前必须等待事件发生,那么您应该查看javascript事件模型。
当你想做一些琐碎的事情时,这是不方便的编程,但很可能你正在使用暂停来等待,以一种可能会遇到竞争条件的方式开始,并且有一种更合适的方式来实现你试图达到的"效果"。
如果你发布你的特定案例,你可能会得到更多关于如何处理这种情况的信息。
干杯,
我知道这个问题有点老,但我有一个类似的问题,我需要模拟一个花了很长时间加载到页面上的脚本。我最终解决了这个问题,创建了一个服务器端端点,该端点在发送响应之前等待了5秒钟,然后在DOM中添加了一个脚本标记来指向这个端点。
尽管如此,它需要一个服务器端实现,但是它允许您在任何特定点停止页面。正如其他人之前所说,这将阻塞整个浏览器,而不仅仅是您的脚本。