有没有比下面的pausecomp函数(取自此处)更好的方法来设计JavaScript中的睡眠?

function pausecomp(millis)
{
    var date = new Date();
    var curDate = null;
    do { curDate = new Date(); }
    while(curDate-date < millis);
}

这不是JavaScript中的Sleep的重复-动作之间的延迟;我希望在函数的中间有一个真正的睡眠,而不是在代码执行之前有一段延迟。


当前回答

从Node.js 7.6开始,您可以将utils模块中的promisify函数与setTimeout结合起来。

const sleep = require('util').promisify(setTimeout)

一般用途

async function main() {
    console.time("Slept for")
    await sleep(3000)
    console.timeEnd("Slept for")
}

main()

问题用法

async function asyncGenerator() {
    while (goOn) {
      var fileList = await listFiles(nextPageToken);
      await sleep(3000)
      var parents = await requestParents(fileList);
    }
  }

其他回答

2021+更新

如果您正在寻找以下替代方案:

let sleep = ms => new Promise(res=>setTimeout(res,ms));

然后使用这个:

let sleep = async ms => void await Atomics.waitAsync(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms).value;

请注意,在发布此问题时,它是第3阶段提案。此外,它可能要求您的站点进行跨源隔离。要查看它在浏览器中是否有效,(在堆栈溢出上)请尝试以下操作:

let sleep=async ms=>void await Atomics.waitAsync(新Int32Array(新SharedArray Buffer(4)),0,0,ms).value;void异步函数(){console.log(1);等待睡眠(2000);console.log(2);}()

需要使用“休眠”方法的对象的方法,如下所示:

function SomeObject() {
    this.SomeProperty = "xxx";
    return this;
}
SomeObject.prototype.SomeMethod = function () {
    this.DoSomething1(arg1);
    sleep(500);
    this.DoSomething2(arg1);
}

几乎可以翻译为:

function SomeObject() {
    this.SomeProperty = "xxx";
    return this;
}
SomeObject.prototype.SomeMethod = function (arg1) {
    var self = this;
    self.DoSomething1(arg1);
    setTimeout(function () {
        self.DoSomething2(arg1);
    }, 500);
}

不同之处在于,“SomeMethod”操作在执行操作“DoSomething2”之前返回。“SomeMethod”的调用者不能依赖于此。由于“睡眠”方法不存在,我使用后一种方法并相应地设计代码。

另一种可能的方式是:

var _timer;
clearTimeout(_timer);
_timer = setTimeout(function() {
    // Your code
}, 1000); // Delay for 1 s.

这里有一个使用同步XMLHttpRequest的简单解决方案:

function sleep(n){
  var request = new XMLHttpRequest();
  request.open('GET', '/sleep.php?n=' + n, false);  // `false` makes the request synchronous
  request.send(null);
}

sleep.php文件的内容:

<?php sleep($_GET['n']);

现在用以下方式调用它:

sleep(5);

使用现有服务器实现

如果您没有自己的应用程序服务器(对于上面的PHP脚本),可以使用一些在线服务。例如:

函数睡眠(n){var request=new XMLHttpRequest();request.open('GET','http://httpstat.us/200?sleep='+n,假);request.send(空);};睡眠(1000);console.log(“一秒延迟完成”);

支持

关于为异步参数传递false,mdn注意到:

主线程上的同步请求很容易破坏用户体验,应该避免;事实上,许多浏览器已完全弃用主线程上的同步XHR支持。Workers中允许同步请求。

实际延迟时间

作为参数传递的毫秒数将是服务器在接收请求和发送响应之间等待的时间。传输和服务器负载所引起的延迟将被添加到其中。

如果你写一个这样的睡眠函数

var sleep = function(period, decision, callback){
    var interval = setInterval(function(){
        if (decision()) {
            interval = clearInterval(interval);
            callback();
        }
    }, period);
}

你有一个异步函数可以多次调用,

var xhr = function(url, callback){
    // Make an Ajax request
    // Call a callback when the request fulfils
}

您的项目设置如下:

var ready = false;

function xhr1(){
    xhr(url1, function(){ ready = true;});
}
function xhr2(){
    xhr(url2, function(){ ready = true; });
}
function xhr3(){
    xhr(url3, function(){ ready = true; });
}

然后您可以执行以下操作:

xhr1();
sleep(100, function(){ return done; }, xhr2);
sleep(100, function(){ return done; }, xhr3);
sleep(100, function(){ return done; }, function(){
    // Do more
});

而不是像这样无休止的回调缩进:

xhr(url1, function(){
    xhr2(url2, function(){
        xhr3(url3, function(){
            // Do more
        });
    });
});