JavaScript睡眠

JavaScript睡眠,javascript,sleep,Javascript,Sleep,是的,我知道——这个问题有成千上万个答案。请不要告诉我关于setTimeout方法的事,因为-是的,这一切都是可能的,但不像使用sleep()方法那么简单 例如: function fibonacci(n) { console.log("Computing Fibonacci for " + n + "..."); var result = 0; //wait 1 second before computing for lower n sleep(1000);

是的,我知道——这个问题有成千上万个答案。请不要告诉我关于
setTimeout
方法的事,因为-是的,这一切都是可能的,但不像使用
sleep()
方法那么简单

例如:

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;
}
函数斐波那契(n){
log(“计算“+n+”的斐波那契函数”);
var结果=0;
//等待1秒,然后计算较低的n
睡眠(1000);

结果=(n我不完全理解你的问题,但我将回答这一部分:

如果你知道如何得到同样的结果 使用setTimeout-告诉我

根本的区别在于
sleep
(在许多其他语言中使用)是同步的,而
setTimeout
(以及许多其他JavaScript概念,例如AJAX)是异步的。因此,为了重写函数,我们必须考虑到这一点。主要是,我们必须使用回调来获取“返回值”,而不是实际的返回语句,因此将按如下方式使用:

fibonacci(7, function(result) {
  // use the result here..
});
因此,在实施方面:

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);
}
函数fibonacci(n,回调){ log(“计算“+n+”的斐波那契函数”); var结果=0; var=函数(){ setTimeout(函数(){ //等待1秒钟后再宣布结果 console.log(“F(“+n+””)=“+result”); 回调(结果);/“返回”值 }, 1000); }; //等待1秒,然后计算下限n setTimeout(函数(){ if(n只需在不使用循环或递归的情况下使用,并避免使用
setTimeout()
/
sleep()

函数斐波那契(n){
返回Math.round(Math.pow((Math.sqrt(5)+1)/2,Math.abs(n))/Math.sqrt(5))*(n<0&n%2?-1:1);
}
用法示例:

// Log the first 10 Fibonacci numbers (F0 to F9) to the console
for (var i = 0; i < 10; i++) {
  console.log(fibonacci(i));
}
//将前10个斐波那契数(F0到F9)记录到控制台
对于(变量i=0;i<10;i++){
log(fibonacci(i));
}

浏览器(或任何其他GUI环境)中的
sleep()
类型函数的问题在于它是一个事件驱动的环境,无法按照您描述的方式
sleep()

setTimeout()
方法之所以有效,是因为它正在创建一个事件,并将该事件的触发器设置为一个时间点。因此,系统可以将等待的控制权交给事件处理程序,Javascript本身可以自由地进行其他操作

在web浏览器中,几乎所有东西都是这样工作的。鼠标单击/悬停/etc函数是事件触发器。Ajax请求不会等待服务器的响应;它们会在收到响应时设置要触发的事件

基于时间的操作也通过事件触发器完成,使用类似于
setTimeout()
的函数

这就是它是如何完成的。事实上,在几乎所有编写良好的GUI应用程序中都是这样做的,因为所有GUI界面都必须能够立即响应鼠标单击等事件

Javascript
sleep()
函数(特别是在这里的另一个答案中实现的方式!)基本上会在等待时钟时消耗CPU周期
将保持活动进程,这意味着其他事件可能不会立即处理-这意味着在睡眠期间,浏览器将停止响应鼠标单击等。这不是一件好事

setTimeout()
是一种方法。总有一种方法可以做到这一点;生成的代码可能不像示例代码那样整洁和线性,但事件驱动的代码很少是线性的——它不可能是线性的。解决方案是将进程分解为小函数。您甚至可以将后续函数嵌入
setTimeout()中
call,这可能会在某种程度上帮助您保持代码至少具有某种线性外观


希望这能帮你解释一些事情。

你到底为什么在计算任何东西的时候想“睡觉”?在任何语言中,睡觉几乎总是一个坏主意。它本质上告诉线程在这段时间内停止做任何事情

因此,在像javascript这样只有一个线程的语言中(忘记“web工作者”),暂停所有计算会带来什么好处?这是个坏主意,算了吧

现在谈谈你写的问题,虽然我不认为这是你真正的问题。为什么在计算这个序列时要暂停一秒钟?即使要计算序列中的前6个数字,也需要8秒左右。为什么?递归调用之间有什么可能的原因要暂停一秒钟?停止。删除它

如果您只想在完成后一秒钟生成最终结果,那么使用setTimeout函数以某种方式使用答案

function fib(n) {
    ...
    result = fib();
    ...
    setTimeout(function() {
        console.log("Fib for " + n + " is " + result);
    },1000);
}

不要尝试实现“睡眠”。不要在计算过程中暂停。

问题是如何在JavaScript中实现
sleep()
,对吗

function sleep(ms) {
  var start = new Date().getTime(), expire = start + ms;
  while (new Date().getTime() < expire) { }
  return;
}
对我有用


(作为一个元注释:我在这里登陆是因为我对这个函数有特殊的需求。当你需要在等待一个值时阻塞时,这种需求确实会出现。即使在JavaScript中也是如此。)

您是否考虑过使用更好的算法?@Yacoby-用于计算斐波那契?这只是一个例子,我知道这非常慢。@Oli-如何将其重写为setTimeout或如何实现工作睡眠()你需要更好地解释你的问题-我知道顺序是什么,但我不知道你想做什么。这个问题是如何得到任何支持的?是否有一种方法在每次打印后刷新控制台?它可能只是缓冲输出。你所说的一切对于异步环境中的Javascript都是正确的。JavaScri没有任何内容pt作为一种坚持异步运行时行为的编程语言。事实上,大多数服务器端Javascript环境都是同步的;Rhino就是一个很好的例子。@Pointy-谢谢;我已经
function sleep(ms) {
  var start = new Date().getTime(), expire = start + ms;
  while (new Date().getTime() < expire) { }
  return;
}
console.log('hello');
sleep(5000);
console.log('world');