好的,所以我有一个使用jQuery的do-while循环。基本上,它的目的是检查目录中是否有照片并将其添加到数组中。该目录的照片都被命名为'phone01.png','phone02.png'等,它们位于一个名为'slide'的目录中。
以下是代码:
var images = [];
var i=0;
do {
++i;
$.get('./slides/phone0' + i + '.png',function(){
images[(i-1)] = './slides/phone0' + i + '.png';
});
}
while ( images[(i-1)] == './slides/phone0' + i + '.png' );
所以如果我最后使用控制台,images []只包含'./slides/phone01.png',但是
我是1
图像[(i-1)]因此是'./slides/phone0'+ i +'。png'
输入( images[(i-1)] == './slides/phone0' + i + '.png' )
会返回true
。所以while语句是真的,但循环不会继续。
此外,如果我再次手动运行循环(迭代i,运行get),get将成功并向数组添加新成员。所以, do函数永远不会再次运行。
是什么给出了?
答案 0 :(得分:3)
$ .get是一个异步请求。因此,您的循环将始终运行一次,因为图像数组永远不会按预期设置。
答案 1 :(得分:1)
这是一个典型的异步问题。
当您致电$.get()
时,它不会立即进入您提供的功能。
它会设置一个HTTP请求,并将该函数作为要求成功时调用的函数附加到请求中。
然后程序的原始部分继续执行它自己的业务,并忘记HTTP请求及其传递给它的函数。
在这种情况下,程序的原始部分是while
循环。一旦它被赋予它的功能,它就会继续并循环while循环。
在(a)HTTP请求成功响应之前,不会触发在循环的每次迭代中创建的函数,以及(b)正在运行的其余Javascript代码停止阻塞线程并给它一个有机会跑。
这称为异步代码,是第一个'A',即'AJAX'一词。这也是整个Javascript的事件处理模型的工作原理,以及您在jQuery中看到的所有嵌套函数。 (这也可以解释您可能已经看到的其他情况,其中代码似乎以错误的顺序运行)。
如果你想用Async代码做这样的循环,你需要用完全不同的方式编写它:你编写的传统while
循环不起作用。
有很多事情要做,但是我不建议只给你一些代码,我建议多做一些关于整个事情是如何工作的,因为如果你要编写Ajax代码,你需要了解这些东西。
我会给你一个提示:全局变量在这种程序中通常不是那么有用。从您的代码示例中不清楚您的变量是否是全局变量,但如果它们是变量,您肯定会考虑将它们作为局部变量并在函数之间传递它们而不是仅仅期望将它们设置在一个位置并且对于它们在另一个人工作。
希望有所帮助。
答案 2 :(得分:1)
首先,对于立即调用的函数表达式如何工作仍然很脆弱,我尝试了这个:
var i=0;
do {
++i;
(function(iteration){
$.get('./slides/phone0' + i + '.png',function(){
images[(i-1)] = './slides/phone0' + i + '.png';
});
})(i);
}
while ( images[(i-1)] == './slides/phone0' + i + '.png' );
尝试强制在while循环中评估GET ......无济于事。我已经解决了以下问题。欢迎任何有关如何有效/清洁的想法。我可能会从太多的C视角思考(函数中的函数! - 在这里插入Xzibit meme)。但这确实可以完成工作:
var i=0;
function createArray(){
$.get('./slides/text0' + (i+1) + '.txt',function(data){
texts.push(data);
});
$.get('./slides/phone0' + (i+1) + '.png',function(){
images[i] = new Image();
images[i].src = './slides/phone0' + (i+1) + '.png';
i++;
createArray();
}).error(function(){
slider();
});
}