Javascript sleep()函数提前执行

spa*_*ara 0 javascript

我试图弄清楚为什么在我的代码部分,this.sleep(5000)似乎在我的绘制函数之前被调用,因为它在睡眠完成之前不会被绘制到画布.任何有关为什么这不符合我想要的方式的见解?

睡眠功能:

sleep: function(milliseconds) {
    setTimeout(function(){
        var start = new Date().getTime();
        while ((new Date().getTime() - start) < milliseconds){
        // Do nothing
        }
    },0);
},
Run Code Online (Sandbox Code Playgroud)

码:

var g = new Graph(this.diagram);
g.DrawPolygons(ctx,"blue");

this.sleep(5000);
Run Code Online (Sandbox Code Playgroud)

Chr*_*ris 5

简短的回答

不要这样做.即使你让它工作,它也会不一致,会给你带来很多问题,而且几乎全球都被认为是不好的做法.

答案很长

JavaScript运行时几乎总是设计为异步的.你的while循环旨在让一切......等等.在大多数JavaScript环境中,您不能(或至少不应该)这样做.

相反,安排事件/功能将ms在未来执行一些.这setTimeout是为了什么.这消除了对sleep功能的需要.

以下是应用上述更改后代码的外观:

var g = new Graph(this.diagram);
g.DrawPolygons(ctx, "blue");

setTimeout(function() {
    g.DrawPolygons(ctx, "red"); // Or whatever

    setTimeout(function() {
       g.DrawPolygons(ctx, "yellow"); // Or whatever

       // etc..
    }, 5000);
}, 5000);
Run Code Online (Sandbox Code Playgroud)

ES2015更新 - 使用承诺

为了避免潜在的深层嵌套setTimeout,您可以使用它

const sleep ms = new Promise(resolve => setTimeout(resolve,ms));
Run Code Online (Sandbox Code Playgroud)

这只是一个以ms毫秒为单位解析的承诺.这允许您将所有内容保存在一个块中:

var g = new Graph(this.diagram);
g.DrawPolygons(ctx, "blue");

(async () => {
  g.DrawPolygons(ctx, "red");
  await sleep(5000);
  g.DrawPolygons(ctx, "yellow");
  await sleep(5000);
  // ...
})()
Run Code Online (Sandbox Code Playgroud)

注意两件事:

  • 在引擎盖下,仍有事件/回调.它看起来像C或Python的睡眠,但行为却截然不同.
  • 您只能在异步函数内部使用它.有关更多信息,请参见此处