JavaScript 睡眠
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4634013/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JavaScript sleep
提问by Diazath
Yes, I know - that question has thousands of answers. please, don't tell me about setTimeout
method because - yes, everything is possible with that but not so easy as using sleep()
method.
是的,我知道——这个问题有成千上万个答案。请不要告诉我setTimeout
方法,因为 - 是的,一切皆有可能,但不像使用sleep()
方法那么容易。
For example:
例如:
function fibonacci(n) {
console.log("Computing Fibonacci for " + n + "...");
var result = 0;
//wait 1 second before computing for lower n
sleep(1000);
result = (n <= 1) ? 1 : (fibonacci(n - 1) + fibonacci(n - 2));
//wait 1 second before announcing the result
sleep(1000);
console.log("F(" + n + ") = " + result);
return result;
}
if you know how to get the same result using setTimeout
- tell me ;) fibanacci is pretty easy task, because there aren't more than 2 recursions, but how about n-recursions (like fib(1) + fib(2) + .. + fib(n)) and sleep after every "+"? Nah, sleep would be muuuuuch easier.
如果您知道如何使用setTimeout
-获得相同的结果- 告诉我;) fibanacci 是一项非常简单的任务,因为不超过 2 个递归,但是 n 递归如何(如 fib(1) + fib(2) + . . + fib(n)) 并在每个“+”之后睡觉?不,睡觉会更轻松。
But still I can't get working example of implementing it. while (curr - start < time) { curr = (...) }
is tricky, but it won't work (just stops my browser and then throw all console logs at once).
但我仍然无法获得实现它的工作示例。while (curr - start < time) { curr = (...) }
很棘手,但它不起作用(只需停止我的浏览器,然后立即抛出所有控制台日志)。
回答by Murph
The question is asking how to implement sleep()
in JavaScript, right?
问题是问如何sleep()
在JavaScript中实现,对吗?
function sleep(ms) {
var start = new Date().getTime(), expire = start + ms;
while (new Date().getTime() < expire) { }
return;
}
I just tested it like so:
我只是这样测试它:
console.log('hello');
sleep(5000);
console.log('world');
Works for me.
为我工作。
(As a meta comment: I landed here because I have a particular need for this function. Such needs do come up when you needto block while waiting for a value. Even in JavaScript.)
(作为元评论:我来到这里是因为我对这个函数有特别的需求。当你需要在等待值时阻塞时确实会出现这种需求。即使在 JavaScript 中也是如此。)
回答by Jakob
I dont fully understand what you're asking, but I'm going to answer this part:
我不完全明白你在问什么,但我将回答这一部分:
if you know how to get the same result using setTimeout - tell me
如果您知道如何使用 setTimeout 获得相同的结果 - 告诉我
The fundamental difference is that sleep
(as used in many other languages) is synchronous, while setTimeout
(and many other JavaScript-concepts, like AJAX for example) are asynchronous. So, in order to rewrite your function we have to take this into account. Mainly, we have to use a callback to fetch the "return value", rather than an actual return-statement, so it will be used like this:
根本区别在于sleep
(在许多其他语言中使用)是同步的,而setTimeout
(以及许多其他 JavaScript 概念,例如 AJAX)是异步的。因此,为了重写您的函数,我们必须考虑到这一点。主要是,我们必须使用回调来获取“返回值”,而不是实际的返回语句,因此它将像这样使用:
fibonacci(7, function(result) {
// use the result here..
});
So, as for the implementation:
所以,至于实现:
function fibonacci(n, callback) {
console.log("Computing Fibonacci for " + n + "...");
var result = 0;
var announceAndReturn = function() {
setTimeout(function() {
// wait 1 second before announcing the result
console.log("F(" + n + ") = " + result);
callback(result); // "returns" the value
}, 1000);
};
// wait 1 second before computing lower n
setTimeout(function() {
if (n <= 1) {
result = 1;
announceAndReturn();
}
else {
var resultsLeft = 2;
var handler = function(returned) {
result += returned;
resultsLeft--;
if (resultLeft == 0)
announceAndReturn();
}
fibonacci(n-1, handler);
fibonacci(n-2, handler);
}
}, 1000);
}
I would also like to point out that, no, this is not an easier solution than using sleep
. Why? Because this code is asynchronous and that's simply more complicated than synchronous code for what most people are used to. It takes practice to start thinking in that way.
我还想指出,不,这不是比使用sleep
. 为什么?因为这段代码是异步的,而且对于大多数人习惯的来说,这比同步代码更复杂。以这种方式开始思考需要练习。
The upside? It allows you to write non-blocking algorithms that outperforms their synchronous counterparts. If you haven't heard of Node.jsbefore, you could check it out to further understand the benefits of this. (Many other languages have libraries for dealing with async IO as well, but as long as were talking about JavaScript..)
好处?它允许您编写性能优于同步算法的非阻塞算法。如果您之前没有听说过Node.js,您可以查看它以进一步了解它的好处。(许多其他语言也有用于处理异步 IO 的库,但只要是在谈论 JavaScript..)
回答by Spudley
The trouble with a sleep()
type function within a browser (or any other GUI environment for that matter) is that it is an event-driven environment, and wouldn't be able to sleep()
in the way you're describing it.
sleep()
浏览器(或与此相关的任何其他 GUI 环境)中的类型函数的问题在于它是一个事件驱动的环境,并且无法按照sleep()
您描述的方式进行。
The setTimeout()
method works because it is creating an event, and setting the trigger for that event to be a point in time. Therefore the system can give over control of the waiting to the event handler and Javascript itself is free to carry on doing other things.
该setTimeout()
方法之所以有效,是因为它正在创建一个事件,并将该事件的触发器设置为某个时间点。因此,系统可以将等待的控制权交给事件处理程序,并且 Javascript 本身可以自由地继续做其他事情。
In the web browser, virtually everything works this way. Mouse click/hover/etc functions are event triggers. Ajax requests don't sit and wait for the response from the server; they set an event to trigger when the response is received.
在 Web 浏览器中,几乎一切都以这种方式工作。鼠标点击/悬停/等功能是事件触发器。Ajax 请求不会坐等服务器的响应;他们设置一个事件以在收到响应时触发。
Time based actions are also done with event triggers, using functions like setTimeout()
.
基于时间的操作也可以通过事件触发器完成,使用诸如setTimeout()
.
This is how it's done. In fact this is how it's done in pretty much any well-written GUI application, because all GUI interfaces must be able to respond to events such as mouse clicks virtually instantly.
这就是它的完成方式。事实上,在几乎所有编写良好的 GUI 应用程序中都是这样做的,因为所有 GUI 界面都必须能够几乎立即响应诸如鼠标点击之类的事件。
A Javascript sleep()
function (especially the way it's been implemented in another answer here!) would basically have the effect burn up your CPU cycles while it waited for the clock. The sleep()
would remain the active process, meaning that other events may not be processed straight away - which means your browser would appear to stop responding to mouse clicks, etc for the duration of the sleep. Not a good thing.
一个 Javascriptsleep()
函数(尤其是它在另一个答案中的实现方式!)基本上会在等待时钟时消耗你的 CPU 周期。在sleep()
将保持活跃的过程,这意味着其他事件可能无法马上处理的-这意味着你的浏览器似乎停止响应鼠标点击等对于睡眠的持续时间。不是什么好事。
setTimeout()
is the way to go. There is always a way to do it; the resulting code may not be neat and linear like your example code, but event-driven code very rarely is linear - it can't be. The solution is to break the process down into small functions. you can even embed the subsequent functions inside the setTimeout()
call, which may go some way to helping you keep your code at least having some appearance of being linear.
setTimeout()
是要走的路。总有办法做到这一点;生成的代码可能不像您的示例代码那样简洁和线性,但事件驱动的代码很少是线性的——它不可能是线性的。解决方案是将过程分解为小功能。您甚至可以在setTimeout()
调用中嵌入后续函数,这可能会在某种程度上帮助您保持代码至少具有某种线性外观。
Hope that helps explain things a bit for you.
希望这有助于为您解释一些事情。
回答by Mathias Bynens
Just use a better algorithmwithout loops or recursion, and avoid the need for setTimeout()
/ sleep()
.
只需使用更好的算法而无需循环或递归,并避免使用setTimeout()
/ sleep()
。
function fibonacci(n) {
return Math.round(Math.pow((Math.sqrt(5) + 1) / 2, Math.abs(n)) / Math.sqrt(5)) * (n < 0 && n % 2 ? -1 : 1);
}
Usage example:
用法示例:
// Log the first 10 Fibonacci numbers (F0 to F9) to the console
for (var i = 0; i < 10; i++) {
console.log(fibonacci(i));
}
回答by Josh Smeaton
Why on earth do you want to 'sleep' while computing anything? Sleeping for any time is nearlyalways a bad idea in any language. It essentially tells the thread to stop doing anything for that period of time.
你到底为什么要在计算任何东西时“睡觉”?在任何语言中,睡觉几乎总是一个坏主意。它本质上是告诉线程在那段时间内停止做任何事情。
So, in a language like javascript that only has one thread (forgetting 'web workers'), what benefit would you reap for pausing ALL computation? It's a bad idea, forget it.
因此,在像 javascript 这样只有一个线程(忘记“网络工作者”)的语言中,暂停所有计算会获得什么好处?这是个坏主意,算了。
Now to the problem that you've written, though I don't think this is your actual problem. Why do you want to pause for a second while computing this sequence? Even to compute the first 6 numbers in the sequence, it's going to take 8 or so seconds. Why? What possible reason is there to pause for a second between recursive calls? Stop it. Remove it.
现在到您写的问题,尽管我认为这不是您的实际问题。为什么在计算这个序列时要暂停一秒钟?即使计算序列中的前 6 个数字,也需要 8 秒左右的时间。为什么?在递归调用之间暂停一秒钟的可能原因是什么?停下来。去掉它。
If you want to just yield the final result a second after it completes, then use setTimeout with a function uses the answer in some way.
如果您只想在完成后一秒钟产生最终结果,那么将 setTimeout 与函数一起使用以某种方式使用答案。
function fib(n) {
...
result = fib();
...
setTimeout(function() {
console.log("Fib for " + n + " is " + result);
},1000);
}
Do not try to implement 'sleep'. Do not pause during computation.
不要试图实现“睡眠”。在计算过程中不要暂停。