JavaScript:在10秒后调用函数,然后每1分钟调用一次。

6
我有以下情景:
我有一个javascript ajax函数loadCars(),需要在页面加载后10秒调用,然后每隔60秒调用一次。
到目前为止,我尝试的方法如下:
setTimeout(function(){setInterval(function(){loadCars()}, 60000)}, 10000);

发生的情况是函数在10秒后被调用,但再也没有被调用了,我漏掉了什么?

@brso05 我不担心,但通常当我给一个问题投反对票时,我会解释为什么。 - Alex
我没有进行过DV,但我可以理解为什么有人会在“不清楚”的情况下进行,因为问题直到评论中才得到充分记录。我仍然很难想象它会按照你所描述的方式运作! - James Thorpe
@AliIssa 是的 - 现在清楚了。但我仍然不明白为什么它会在10之后做这件事,然后就不再做了 :) - James Thorpe
@JamesThorpe 我不同意...你应该说出原因,这样用户就有机会修复问题,如果你不说原因,那么还会有很多错误的答案和问题需要修复... - brso05
2
@JamesThorpe 这就是我的问题,也是我在这里提问的原因 :) - Alex
显示剩余7条评论
4个回答

7
你需要在 setTimeoutsetInterval 上调用 loadCars

setTimeout(function() {
    console.log('first 10 secs');
    // loadCars();
  
    setInterval(function() {
          console.log('60 secs has passed');
          // loadCars();
    }, 60000);

}, 10000);
console.log('page loaded');


setInterval是不好的做法,它不会等待函数执行完成。 - koningdavid
我并没有写过setInterval是一个好的实践。我只是回答了问题,修复了代码。 - rogeriolino

2
我不同意之前给出的答案,因为它们使用setInterval或者没有等待ajax调用完成。在我看来,你应该只有在loadcars函数(以及ajax调用)完成后才设置一个新的timeout。 示例:
function loadCars () {
  // ajax call happens here
  $.ajax()
    .then(function(){
      // call the function here
      setTimeout(function(){
        loadCars();
      // wait a minute after you recieved the data
      }, 60000)
    })
}

// wait 10 seconds
setTimeout(function(){
  loadCars();
}, 10000)

这样做的优点是,当HTTP请求完成并防止函数出现不同步时,它只会开始设置新的超时。如果您将setinterval与ajax调用结合使用,则即使当前ajax已延迟10秒钟(而您不想要这种情况),下一个ajax调用也将在60秒后发生。


1
正确,但是(在你的例子中)你没有等待请求完成。 - skobaljic
1
@brso05 嗯,他们也没有考虑到 ajax 调用可能会延迟。 - koningdavid
你能真的使用 $.ajax().then() 吗? - skobaljic
1
@brso05 succes() 方法已经被弃用,而且将会在失败时触发,所以我认为这样做更好。 - koningdavid
@brso05,您在谈论未被弃用的参数,但最好遵循新标准并使用done()而不是success()。无论如何,离题了。 - koningdavid

1
你可以在你的loadCars()方法中调用setTimeout(loadCars, 60000),这样你就可以使用setTimeout最初的10秒钟进行一次调用,然后从那个时间点开始,每次执行都会设置一个1分钟的超时...
function loadCars()
{
    //code
    setTimeout(loadCars, 60000);
}

setTimeout(loadCars, 10000);

如果你希望下一个超时仅在 ajax 调用完成后才被安排,则可以进行同步的 ajax 调用,或者将 setTimeout() 放置在 ajax 调用的 success 回调函数中... 后者是更好的选择。

同步ajax最好避免使用(除了在WebWorkers之外)。规范警告正在被移除的过程中,实际上Chrome(不确定其他浏览器)已经记录了建议的警告。 - James Thorpe
@JamesThorpe,你说得对,这就是为什么我提供了第二个(更好的)选项,将它放在“success”回调函数中。 - brso05
确实如此。但我会把推荐/更好的选项放在第一位 :) - James Thorpe

1

如果您想更好地控制时间和函数调用,可以通过以下方式指定它们:

function loadCars() {
    $('#log').append('Cars loaded<br />');
};
function loadManufacturers() {
    $('#log').append('Manufacturers loaded<br />');
};
function loadCustomers() {
    $('#log').append('Customers loaded<br />');
};
function loadContent(delays, functions) {
    if (functions.length) {
        setTimeout(function () {
            functions.pop()();
            loadContent(delays, functions);
        }, delays.pop());
    };
};
loadContent([3000, 2000, 1000], [loadCars, loadManufacturers, loadCustomers]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p id="log"></p>

Playground

可以直接翻译为:

{{链接1:游乐场}}

,其中保留了HTML标签和占位符。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接