提问者:小点点

JavaScript睡眠[重复]


是的,我知道--这个问题有成千上万个答案。 请不要告诉我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;
}

如果您知道如何使用settimeout-告诉我;)fibanacci非常容易,因为它的递归不超过2个,但是n-递归如何(如fib(1)+fib(2)+)。。。 +fib(n))然后在每个“+”之后睡觉?不,睡觉会更容易。

但我仍然无法获得实现它的工作实例。 while(curr-start很棘手,但它不会工作(只需停止浏览器,然后一次抛出所有控制台日志)。


共3个答案

匿名用户

我不完全明白你在问什么,但我要回答这一部分:

如果您知道如何使用setTimeout获得相同的结果-请告诉我

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

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

我还要指出,不,这不是一个比使用sleep更容易的解决方案。 为什么? 因为这段代码是异步的,而且对于大多数人来说,这只是比同步代码更复杂。 开始那样思考需要练习。

好的一面? 它允许您编写性能优于同步算法的非阻塞算法。 如果您以前没有听说过Node.js,您可以查看一下它,以进一步了解它的好处。 (许多其他语言也有处理异步IO的库,但只要是JavaScript.。。)

匿名用户

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

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

对我有效。

(作为一个元注释:我之所以选择这里,是因为我特别需要这个函数。当您在等待值时需要阻塞时,就会出现这种需求。即使在JavaScript中也是如此。)

匿名用户

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

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

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

基于时间的操作也可以通过事件触发器完成,使用诸如setTimeout()之类的函数。

就是这样做的。 事实上,几乎所有编写良好的GUI应用程序都是这样做的,因为所有的GUI界面都必须能够即时响应诸如鼠标单击之类的事件。

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

setTimeout()是可行的方法。 总有办法做到的; 结果代码可能不像示例代码那样整洁和线性,但是事件驱动代码很少是线性的--它不可能是线性的。 解决方案是将过程分解为小的功能。 您甚至可以在setTimeout()调用中嵌入后续函数,这可能有助于使代码至少具有某种线性的外观。

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