延迟JavaScript函数的执行

8

我有一个JQuery的.each循环,每次迭代都调用一个带有参数的函数,有没有一种延迟这个函数调用的方法?我尝试了以下的setTimeout,但是这并不起作用,因为该函数会立即执行。

$.each(myArray, function (j, dataitem)
{
     setTimeout(function () { showDetails(dataitem) }, 300);
});

function showDetails(dataitem)
{
...
}

数组大小大约为20,我想做的是在一定时间范围内分配函数调用,而不是立即执行。有什么办法可以实现这个目标吗?我准备重写和重新结构化函数调用方式来完成这个任务,非常感谢您的帮助。


3
执行肯定被推迟了,但循环不会被推迟,也就是说所有20个setTimout几乎一起被调用。您是否想一个接一个地调用showDetail函数?我的意思是,第一个在300毫秒后调用,第二个在600毫秒后调用,依此类推。 - Felix Kling
4个回答

10
您可以使用数组的索引动态计算间隔:
$.each(myArray, function (j, dataitem) {
    window.setTimeout(function () { 
        showDetails(dataitem) 
    }, (j + 1) * 300);
});

现在我重新阅读了问题,这似乎是问题提问者试图做的事情。+1 - Russ Cam
1
window.前缀真的有必要吗?我不认为有人会覆盖setTimeout这个名称。 - Šime Vidas
@Šime Vidas,我更喜欢始终使用适当的作用域。这是良好的实践。 - Darin Dimitrov
1
你是针对window对象的所有属性(例如window.parseIntwindow.console.logwindow.document.getElementById等)都这样做吗? - Šime Vidas

2

您在 300 毫秒后执行全部。相反,尝试使用以下方法:

window.setTimeout(function () { showDetails(dataitem) }, (j + 1) * 300);

编辑:不要一次性创建20个定时器,最好逐个创建。函数应该如下:

function showDetails(index)
{
   if (index >= myArray.length)
      return false;
   var dataItem = myArray[index];
   //code here......
   //code here......
   //code here......
   windows.setTimeout(function() { showDetails(index + 1); }, 300);
}

首先的调用可以是:

$(document).ready(function() {
{
   showDetails(0);
});

假设myArray是普通的全局数组,它将处理一个项目,然后延迟调用下一个项目。

谢谢,我已经尝试过这个方法并且它有效。不过我选择了第一个答案,因为对我来说在代码中更容易阅读。+1 :) - Maya

2
请看 jQuery.queue([ queueName ], callback( next )),这允许您排队调用函数,正是jQuery动画效果内部所使用的。
听起来像是您想要实现一个队列,尽管您的意图还不是很清楚。 编辑: 重新阅读您的问题后,我认为其他答案更符合您的需求,但我想向您展示如何借助自定义队列实现延迟执行功能的示例。
一个关于如何使用队列的示例
var myArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],
    output = $('#output');

// set the queue up
$.each(myArray, function (j, dataitem) {
    output.queue('queue', function(next) {
        var that = this;
        showDetails(dataitem);  
        window.setTimeout(next,300);
    });
});

// start the queue running.
output.dequeue('queue');

function showDetails(dataitem) {
    output.append('<div>' + dataitem + '</div>');
}

这实际上是有用的知识。+1 :) - Maya

0

不要使用$.each,而是使用类似以下的东西:

var data = [1, 2, 3, 4, 5];

function showDetails(values, delay) {
  console.log(values.shift()); //show the value
  if (values.length) {
    setTimeout(function() {showDetails(values, delay); }, delay); //schedule next elem
  }
}

showDetails(data.slice(0), 300); //dont forget the slice, call-by-reference

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