如何在JavaScript中创建真正的sleep()?

如何在JavaScript中创建真正的sleep()?,javascript,Javascript,我知道有很多方法,比如setTimeout,但我只想要一个真正的方法 我正在使用JavaScript编写编译器,我必须找到一种实现sleep()函数的方法。 我知道那辆四轮马车的路线,这不是我想要的 谢谢。如果您只想在X毫秒内调用函数,您可以使用setTimeout,但您知道这一点 您可以使用Date和getTime将内容组合在一起 function sleep(milliseconds) { var now = new Date(); var exitTime = now.ge

我知道有很多方法,比如setTimeout,但我只想要一个真正的方法

我正在使用JavaScript编写编译器,我必须找到一种实现sleep()函数的方法。 我知道那辆四轮马车的路线,这不是我想要的


谢谢。

如果您只想在X毫秒内调用函数,您可以使用
setTimeout
,但您知道这一点

您可以使用Date和
getTime
将内容组合在一起

function sleep(milliseconds) {
    var now = new Date();
    var exitTime = now.getTime() + milliseconds;
    while (true) {
        now = new Date();
        if (now.getTime() > exitTime)
        return;
    }
}

但是您完全冻结了当前线程一段可能很长的时间。我认为您基本上会停止页面上的所有javscript操作X毫秒,如果时间大于300毫秒,这将是非常恼人的


如果你给我们多一点背景,我们可能会更有帮助。睡眠通常在其他语言的多线程场景中使用,这正是为什么javascript中没有使用睡眠。您的编译器需要哪些功能D

至少在大多数浏览器实现中,您不能这样做。你必须让你的编译器解决这个问题。做类似的事情

我会补充一些细节。显然,这并不是实现睡眠功能的最佳方式,但既然您说您正在使用一种简单的绘图语言,我就这样说:

假设您有如下代码:

drawLine(1, 2, 3, 4);
sleep(1000);
drawLine(5, 6, 7, 8);
通过打破所有的
睡眠
s可以将其转换为:

var pieces;
function advance() {
    pieces.shift()();
}
pieces=[
    function() {
        drawLine(1, 2, 3, 4);
        setTimeout(advance, 1000);
    },
    function() {
        drawLine(5, 6, 7, 8);
    }
];
advance();
或者,如果您的语言比这更复杂,您可以对编译器进行更复杂的操作(这是显而易见的解决方案):


同样,如果您的语言变得非常复杂,这可能不适用,但作为一个起点,它可能会有所帮助。

从上面的答案中,我推断您需要一个不冻结浏览器、不使用setTimeout的睡眠功能


祝你好运,javascript是单线程的这是不可能的

听起来像是你想做一个区块循环

while(condition) {
    // do something
    sleep(x);
}
把它变成

function foo(values) {
    if(condition) {
         // do something
         setTimeout(function() {
            foo(values); 
         }, x);
    }
}
foo(someValue);
function foo(i) {
    // do something
    i++;
    if (i < n) {
        setTimeout(function() {
            foo(i);
        }, x);
    }
}
foo(0);
你也可以做一个for循环

for (var i = 0; i < n; i++) {
    // do something
    sleep(x);
}
(变量i=0;i{ //做点什么 睡眠(x); } 把它变成

function foo(values) {
    if(condition) {
         // do something
         setTimeout(function() {
            foo(values); 
         }, x);
    }
}
foo(someValue);
function foo(i) {
    // do something
    i++;
    if (i < n) {
        setTimeout(function() {
            foo(i);
        }, x);
    }
}
foo(0);
函数foo(i){ //做点什么 i++; if(i 基本上,将循环转换为递归调用,然后用异步递归调用替换休眠


在一个循环中,你需要用身体阻挡来减慢脚步。在递归中,您可以延迟对下一个递归函数的调用。

在JavaScript中实现
sleep()
的唯一真正合理的方法是使用
setTimeout
。只需逐个处理编译的指令,然后在遇到睡眠指令时休息一下:

function resume() {
    while (instructions.length) {
        var instruction = instructions.shift();

        switch (instruction.opcode) {
        case "foo":
            doFoo(instruction.operands);
            break;
        case "bar":
            doBar(instruction.operands);
            break;
        case "sleep":
            doSleep(instruction.operands);
            return; // pause running
        }
    }
}

function doSleep(operands) {
    setTimeout(resume, operands[0]);
}

var instructions = compile(source);
resume();

你是说真的?您的设计要求是什么?为什么在编译代码时需要sleep()?如果您计划在浏览器中运行此代码,并且您的目标不是冻结UI,那么这不是一个好主意。我正在编写一个编译器,而原始语言有一个sleep()函数。Javascript是编译器的开发语言还是目标环境的开发语言?换句话说,您只是在用Javascript编写编译器,还是编译器会生成Javascript作为“机器语言”在浏览器或其他JS运行时运行?谢谢,但这不是我想要的…它是一个CPU燃烧器。@Xhacker您想要什么?在这一点上,我们所能做的就是猜测。你为什么需要睡觉?你的要求是什么我想设计一个简单的脚本语言,主要功能是绘制基本图形。使用sleep函数,它可以制作一些简单的动画。@XhackerLiu为什么要使用
sleep
而不是
delay(recursiveCallback)
。不要像对待C一样对待javascript@Raynos我只是想把另一种脚本语言转换成javascript。你的意思是我不能实现sleep()函数吗?@Xhacker Liu:我就是这么说的。但是,您可以让编译器将同步代码转换为异步代码,从而避免这个问题。为什么大家仍然认为每个Javascript程序都在浏览器中运行?:-)@paxdiablo:不,我知道还有其他的实现。这就是为什么我说“至少在大多数浏览器实现中”。icktoofay的解决方案是正确的。在这个场景中,您负责编译器,所以我会让它生成延续,并通过
setTimeout
实现休眠。单线程javascript===无法在不阻塞的情况下休眠线程。@Xhacker他刚才说javscript是单线程的,这意味着它完全没有线程或并发的概念D