JavaScript休眠[重复]

uoifb46i  于 2023-01-24  发布在  Java
关注(0)|答案(5)|浏览(96)
    • 此问题在此处已有答案**:

(91个答案)
九年前就关门了。
是的,我知道-这个问题有成千上万的答案。请不要告诉我关于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 < time) { curr = (...) }是棘手的,但它不会工作(只是停止我的浏览器,然后抛出所有的控制台日志一次)。

ct2axkht

ct2axkht1#

问题是如何在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');

对我有用。
(As元评论:我来到这里是因为我对这个函数有特殊的需求,当你在等待一个值的时候需要阻塞的时候,这种需求就会出现,即使在JavaScript中也是如此。)

ibrsph3r

ibrsph3r2#

我不太明白你在问什么,但我会回答这个问题:
如果您知道如何使用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);
}

我还想指出的是,,这并不是一个比使用sleep更简单的解决方案。为什么?因为这段代码是异步的,对于大多数人来说,这比同步代码更复杂。需要练习才能开始这样思考。
好处是什么?它允许您编写性能优于同步算法的非阻塞算法。如果您以前没有听说过Node.js,您可以查看它以进一步了解它的好处。(许多其他语言也有处理异步IO的库,但只要我们讨论JavaScript......)

o8x7eapl

o8x7eapl3#

浏览器(或任何其他GUI环境)中的sleep()类型函数的问题在于,它是一个事件驱动的环境,不能像您描述的那样使用sleep()
setTimeout()方法之所以有效,是因为它创建了一个事件,并将该事件的触发器设置为一个时间点,因此系统可以将等待的控制权交给事件处理程序,而Javascript本身可以自由地继续做其他事情。
在Web浏览器中,几乎所有的功能都是这样工作的:鼠标点击/悬停等功能都是事件触发器; AJAX 请求不会坐等服务器的响应;它们设置在接收到响应时触发的事件。
基于时间的动作也可以通过事件触发器来完成,使用setTimeout()之类的函数。
这就是它是如何实现的,事实上,这是几乎所有编写良好的GUI应用程序的实现方式,因为所有的GUI界面必须能够响应事件,比如鼠标点击,几乎是即时的。
一个Javascript sleep()函数(特别是在这里的另一个答案中它的实现方式!)基本上会在等待时钟的同时消耗掉你的CPU周期。sleep()将保持活动进程,这意味着其他事件可能不会立即被处理-这意味着你的浏览器似乎停止响应鼠标点击,等睡眠的持续时间。不是一件好事。
setTimeout()是要走的路,总有办法做到;生成的代码可能不像你的示例代码那样简洁和线性,但是事件驱动的代码很少是线性的--它不可能是线性的。解决方案是把这个过程分解成小函数。你甚至可以把后续的函数嵌入到setTimeout()调用中,这可能会在某种程度上帮助你保持你的代码至少有一些线性的外观。
希望这能帮你解释一下。

epfja78i

epfja78i4#

只需使用a better algorithm,而不需要循环或递归,并且避免使用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);
}

用法示例:

// Log the first 10 Fibonacci numbers (F0 to F9) to the console
for (var i = 0; i < 10; i++) {
  console.log(fibonacci(i));
}
z4iuyo4d

z4iuyo4d5#

为什么你想在计算的时候“休眠”呢?在任何语言中,休眠任何时间几乎都是一个坏主意。它本质上告诉线程在这段时间内停止做任何事情。
那么,在javascript这样只有一个线程的语言中(忘记了“网络工作者”),暂停所有计算会有什么好处呢?这是个坏主意,忘了它吧。
现在到你写的问题,虽然我不认为这是你真正的问题,为什么你想在计算这个序列的时候,暂停一秒钟,即使是计算序列的前6个数字,也要花8秒钟左右,为什么?,在递归调用之间,有什么可能的原因要暂停一秒钟呢?,停止它,删除它。
如果您只想在它完成一秒钟后产生最终结果,那么可以使用setTimeout,函数以某种方式使用答案。

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

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

相关问题