Javascript Javascript递归设置超时

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5559510/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 17:48:37  来源:igfitidea点击:

Javascript recursion settimeout

javascriptrecursionsettimeout

提问by Paul

I have just started looking at javascript so hopefully this will be something simple. I want to make a slideshow of images that plays automatically. This is very simple, and there are a few tutorials on it but for some reason I haven't been able to get it to work. This is what I have:

我刚刚开始研究 javascript,所以希望这会很简单。我想制作自动播放的图像幻灯片。这非常简单,并且有一些关于它的教程,但由于某种原因我无法让它工作。这就是我所拥有的:

var image1 = new Image();
var image2 = new Image(); 
var image3 = new Image();
image1.src = "images/website6.jpg";
image2.src = "images/website7.jpg";
image3.src = "images/sunset.jpg";
var images = new Array(
  "images/website6.jpg",
  "images/website7.jpg",
  "images/sunset.jpg"
);
setTimeout("delay(images,0)",2000);
function delay(arr,num){
  document.slide.src = arr[num % 3];
  var number = num + 1;
  setTimeout("delay(arr,number)",1000);
}

The image I'm trying to change has id slide. And I also have some evidence that it works. What happens is the first image loads. Then the second image loads (which means the original setTimeout call must be working). Then nothing happens. Which to me suggests it's the recursion that isn't working.

我正在尝试更改的图像具有 id 幻灯片。我也有一些证据表明它有效。发生的是第一个图像加载。然后加载第二个图像(这意味着原始 setTimeout 调用必须有效)。然后什么也没有发生。对我来说,这表明递归不起作用。

I am very familiar with recursion in other languages, so I think it must just be a syntax thing or something, but I can't seem to figure it out. Thanks for any help.

我对其他语言中的递归非常熟悉,所以我认为它一定只是一个语法东西什么的,但我似乎无法弄清楚。谢谢你的帮助。

回答by Pointy

The problem is that when you pass in strings to be evaluated to the setTimeoutcall, the evaluation will be done (later, when it's time to fire) in the global context. Thus, you're way better off (for a lot of other reasons) passing in actual functions:

问题是,当您将要评估的字符串传递给setTimeout调用时,评估将在全局上下文中完成(稍后,当需要触发时)。因此,您最好(出于许多其他原因)传入实际函数:

setTimeout(function() { delay(images, 0); }, 2000);

function delay(arr, num) {
  document.slide.src = arr[num % 3];
  setTimeout(function() { delay(arr, num + 1); }, 1000);
}

In more modern browsers, you can use the .bind()method for functions to create a function that's pre-bound to something to be used as this:

在更现代的浏览器中,您可以使用.bind()函数的方法来创建一个预先绑定到要用作的东西的函数this

setTimeout(delay.bind({arr: images, num: 0}), 2000);

function delay() {
  document.slide.src = this.arr[this.num % 3];
  setTimeout(delay.bind({arr: this.arr, num: this.num + 1}), 1000);
}

Six of one, half-dozen of the other, but just as an example that shows there are multiple ways to do things.

一个六个,另一个六个,但这只是作为一个例子,表明有多种方法可以做事。

回答by JaredPar

I would be very suspicious of the second setTimeoutcall. I would make it clearer by using an explicit function vs. a string expression

我会非常怀疑第二个setTimeout电话。我会通过使用显式函数与字符串表达式使其更清晰

setTimeout(function() { delay(arr, number); }, 1000);