Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/415.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 具有相同间隔的多个setTimeout()函数的执行顺序_Javascript - Fatal编程技术网

Javascript 具有相同间隔的多个setTimeout()函数的执行顺序

Javascript 具有相同间隔的多个setTimeout()函数的执行顺序,javascript,Javascript,考虑以下Javascript代码: function(){ setTimeout(function() { $("#output").append(" one "); }, 1000); setTimeout(function() { $("#output").append(" two "); }, 1000); } 您还可以在上看到此示例 我是否可以确保#output的值始终是“一二”,按该顺序排列?通常,我会这样处理这个问题:

考虑以下Javascript代码:

function(){
    setTimeout(function() {
        $("#output").append(" one ");
    }, 1000);
    setTimeout(function() {
        $("#output").append(" two ");
    }, 1000);
}
您还可以在上看到此示例

我是否可以确保
#output
的值始终是
“一二”
,按该顺序排列?通常,我会这样处理这个问题:

function(){
    setTimeout(function() {
        $("#output").append(" one ");
        $("#output").append(" two ");
    }, 1000));
}
但我不能这样做,因为我从一个服务器收到消息,它告诉我要执行哪个函数(在本例中是append
“one”
或append
“two”
),我必须稍微延迟执行

我已经在Internet Explorer 9、Firefox 14、Chrome 20和Opera 12中测试过这段代码,输出总是
“一二”
,但我能确定这会一直是这样吗?

不,你不能确定。它是异步的


但事实上,这可能是真的,因为该机制在浏览器中实现了。

是的,输出将始终是
“一二”


因为第一个
setTimeout
总是在第二个
setTimeout
之前运行,如果它们具有相同的延迟时间,那么第一个的回调函数总是在第二个的回调函数之前执行。

是,因为javascript代码在一个线程中执行,所有异步事件,像
单击
鼠标移动
,都排队执行。当您调用
setTimeout
时,引擎将在其队列中插入一个计时器,以便将来执行,至少在
delay
时间之后执行。因此,两个
setTimeout
会一个接一个地生成两个计时器


你可以看看约翰·雷斯格的作品。

在你的小提琴里摆弄一下

$(document).ready(function() {
    setTimeout(function() {
        $("#output").append(" one ");
    }, 1000);
});
$(document).ready(function() {
    setTimeout(function() {
        $("#output").append(" two ");
    }, 999);
});​
你会看到这两者

output: one two
output: two one
这是可能的。所以Speransky是对的,你不能总是依赖于你的超时以相同的顺序执行

注意,我用1ms更改了一次,以显示在999ms超时之前可以执行1000ms超时

编辑:下面的代码可以延迟执行,而不会在
one
之前打印
two

function(){
    setTimeout(function() {
        $("#output").append(" one ");
       setTimeout(function() {
           $("#output").append(" two ");
       }, 100);
    }, 1000);
}

更新
我已经用这个方法更新了你的小提琴

这个方法怎么样--从您的服务器获取一个要做的事情的列表--


通过这种方式,您可以决定顺序。

如果事件是同步的,则有
Continuum
函数按顺序运行函数:

function keyedSequence(key, fn) {
  fn = fn || this;
  key.push({fn:fn});

  return function() {
    for(var i=0, n, full=1; i<key.length; i++) {
      n = key[i];
      if(n.fn == fn) {
        if(!n.called) n.called = 1, n.args = key.slice.call(arguments);
        if(!full) break
      }
      if(!n.called) full = 0
    }

    if(full) for(i=0; i<key.length; i++)
      n = key[i], key[i] = {fn:n.fn}, n.fn.apply(n, n.args);
  }
}
Function.prototype.seq = keyedSequence;
单击
test2
,然后单击
test1
,执行顺序仍然是
function1
然后是
function2

另一种说法是:

window.onload = function() {
  var key = [];
  document.getElementById("test1").addEventListener('click', keyedSequence(key, function1), false);
  document.getElementById("test2").addEventListener('click', keyedSequence(key, function2), false);
}
规格是

我对第7.3节中
setTimeout
步骤8的解释是执行顺序应该得到保证



然而,我调查了这个问题,因为当窗口在Chrome中最小化然后最大化时,我发现来自外部源(如WebSocket或webworkers)的事件中设置的超时以错误的顺序执行。我假设这是一个浏览器错误,希望很快就能修复。

这取决于浏览器,因为setTimout是浏览器中窗口对象的一部分,而不是在ECMAScript中定义的。

根据规范,应该订购具有相同任务源的内容。所以是的

您需要延迟执行的原因是什么?在这里您可以找到HTML5中的计时器规范:一种解决方案是延迟计时器本身。我已经提出了一个可能的解决方案如果你关心执行顺序,你可能想看看这个页面@SperanskyDanil的可能重复,即使差异小于1ms,但顺序是固定的。这不是所问的op,在他的问题中,
setTimeout
的执行顺序是固定的,如果插入第一个计时器的时间超过1ms,则结果是
“一拖”
。但是如果不到1ms,结果是
“两个一”
。我在不同的浏览器中使用过这个,但我总是得到结果
“两个一”
,可能是因为我有一台相当快的电脑;)我可以想象,在其他PC上,顺序可能不同,但我总是使用相同的时间间隔(如果我无法确保问题中所问的执行顺序,我必须寻找另一种解决方案)。请查看上述注释中的链接,这些注释来自
一些
,请参见
,此API不能保证计时器完全按计划运行。CPU负载、其他任务等可能会导致延迟。
第9点关于用户代理时间。即使javascript在单个线程上执行,其行为也可能与您预期的不同。我使用Chrome 20.0.1132.57 m进行测试。可能您正在使用不同的浏览器。当我们使用这段代码时,它会执行不同的操作。如果你依赖执行命令,那是非常危险的!我认为
不能保证。。完全按计划
意味着
设置超时(func,1000)
计时器不能保证在1000毫秒后执行。这并不能回答我原来的问题。我只是想解释为什么我不能使用我在问题中提出的第二种方法。如果我不能以相同的时间间隔使用setTimeout()确保执行顺序,我必须寻找另一个适合我的应用程序的解决方案。但是我不能使用第二个解决方案。感谢您指向规范!根据您的经验,您可以告诉我不要依赖于此。我无法在提供的链接中找到第7.3节?内容改变了吗?此外,我还附加了以下内容:“此API不能保证计时器完全按计划运行。CPU负载、其他任务等导致的延迟是意料之中的。”是的,现在已经过了相当长的一段时间,规范文档也发生了更改。问题不在于计时器是否完全按计划启动,而在于它们是否按预期顺序启动,即使有延迟。我相信,由于Javascript的“转向”特性,WebSocket或webworkers将执行
window.onload = function() {
  var key = [];
  document.getElementById("test1").addEventListener('click', function1.seq(key), false);
  document.getElementById("test2").addEventListener('click', function2.seq(key), false);
}
window.onload = function() {
  var key = [];
  document.getElementById("test1").addEventListener('click', keyedSequence(key, function1), false);
  document.getElementById("test2").addEventListener('click', keyedSequence(key, function2), false);
}