javascript 在javascript中循环调用函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18312016/
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
calling function in a loop in javascript
提问by Hazem
I am trying to call a function from within a loop in a way that when the function finishes executing, the loop continues to the next iteration and calls it again. But instead the loop doesn't wait for the function to finish and instead calls 4 instances of the function and runs them at the same time! Should I put the whole function in the loop or is there to make the loop wait for the function to be executed? Thanks
我试图从循环中调用一个函数,当函数完成执行时,循环继续下一次迭代并再次调用它。但是循环不会等待函数完成,而是调用函数的 4 个实例并同时运行它们!我应该把整个函数放在循环中还是让循环等待函数被执行?谢谢
for (var i=2; i<=4; i++){
galleryAnimation(i); //This is executed 3 times at once
}
function galleryAnimation(i){
$("#pic" + i).delay(delayTime).fadeIn(duration);
}
采纳答案by Tomalak
Simplistic solution: Increase the timeout by a factor every time.
简单的解决方案:每次将超时增加一个因子。
var i, factor,
duration = 250,
delayTime = 500;
for (i = 2, factor = 0; i <= 4; i++, factor++) {
galleryAnimation(i, factor);
}
function galleryAnimation(i, factor) {
$("#pic" + i).delay(factor * delayTime).fadeIn(duration);
}
This runs the same way your approach does, only the delays get longer every time.
这与您的方法的运行方式相同,只是每次延迟都会变长。
Generic solution 1 - work with setInterval()
to have your worker function (the one that does the fadeIn
) called in predefined intervals:
通用解决方案 1 - 使用setInterval()
以fadeIn
预定义的时间间隔调用您的工作函数(执行 的那个):
var elements = $("#pic2,#pic3,#pic4").toArray(), // or any other way to select your elements
duration = 250,
delayTime = 500,
intervalId = setInterval(function () {
$(elements.shift()).fadeIn(duration);
if (elements.length === 0) {
clearInterval(intervalId);
}
}, delayTime);
Generic solution 2 - work with callbacks that are called when the previous animation finishes:
通用解决方案 2 - 使用在上一个动画完成时调用的回调:
var elements = $("#pic2,#pic3,#pic4").toArray(), // or any other way to select your elements
duration = 250,
delayTime = 500,
next = function () {
$(elements.shift()).delay(delayTime).fadeIn(duration, next);
};
next(); // start the chain
回答by bluehallu
The function is being executed 3 times just like you requested, the problem is that both delay and fadeIn use timers: they set a timer in the future when the function will be executed and return immediately: they are non-blocking calls. So, in your case, because you're calling the function 3 times at, let's say, 0.0001s, 0.0002s, and 0.0003s, the three kick in at, let's say, 5.0001, 5.0002 and 5.0003.
该函数按照您的要求执行了 3 次,问题在于延迟和淡入淡出都使用计时器:它们在将来执行函数并立即返回时设置了一个计时器:它们是非阻塞调用。因此,在您的情况下,因为您在 0.0001s、0.0002s 和 0.0003s 处调用该函数 3 次,所以这三个函数在 5.0001、5.0002 和 5.0003 处启动。
What you had in mind were blocking callsto these functions. You expected the whole execution to stop until the animations were finished. This would stop the whole browser Javascript engine for the duration, meaning no other animation or user javascript interaction would be possible.
您想到的是阻止对这些函数的调用。您希望整个执行停止,直到动画完成。这将在一段时间内停止整个浏览器 Javascript 引擎,这意味着不可能有其他动画或用户 javascript 交互。
To solve it, you have to use callbacks. You can supply a function to fadeIn that will be called once the animation has completed:
要解决它,您必须使用 callbacks。您可以为fadeIn 提供一个函数,该函数将在动画完成后调用:
You can use queues to simulate the same on delay():
您可以使用队列在 delay() 上模拟相同的内容:
回答by Hazem
I came with my own solution that seemed to work perfectly, this is my code:
我带来了我自己的解决方案,它似乎运行良好,这是我的代码:
function fadeInAnimation(index){
$("#pic" + index).delay(delayTime).fadeIn(duration, function(){
photoIndex();
});
}
function photoIndex(){
index++;
fadeInAnimation(index);
}
fadeInAnimation(index);
});
I have realized that using loops is a really bad idea with things like this. This code will allow me to add as many images as I want just by renaming them in the folder rather than coding them in manually as callbacks for each photo. Thanks for those who answered. Your suggestions are great and will definitely remember them in other applications like this one
我已经意识到在这样的事情上使用循环是一个非常糟糕的主意。这段代码将允许我添加任意数量的图像,只需在文件夹中重命名它们,而不是手动将它们编码为每张照片的回调。谢谢回答的人。你的建议很棒,肯定会在其他应用程序中记住它们,比如这个
回答by Nadeem_MK
one thing you can do, is to use an identifier (boolean) and then, in the loop, you test the identifier to decide if the loop can continue or stop.
For example,
function galleryAnimation(i, iBool){
$("#pic" + i).delay(delayTime).fadeIn(duration);
iBool = 0;
}
您可以做的一件事是使用标识符(布尔值),然后在循环中测试标识符以确定循环是否可以继续或停止。例如,
function galleryAnimation(i, iBool){
$("#pic" + i).delay(delayTime).fadeIn(duration);
iBool = 0;
}
Then on the return;
然后在返回;
for (var i=2; i<=4; i++){
galleryAnimation(i, iBool);
// If iBool = 0 then continue
// Else Break
}
that might be a solution, as the loop will need the returning value to determine the next step, to continue or break.
这可能是一个解决方案,因为循环需要返回值来确定下一步是继续还是中断。