xhr响应,for循环不起作用 [英] xhr response with for loop not working
问题描述
我有for循环的xhr,它非常罕见
i have xhr with for loop and it work very rare
for(var i = 0; i < this.files.length; i++) {
var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function(e) {
};
xhr.onreadystatechange = function(e) {
if(this.readyState === 4) {
console.log(xhr.responseText);
}
};
var formdata = new FormData();
formdata.append("files", this.files[i]);
console.log(this.files[i]);
xhr.open('POST', 'slike.php');
xhr.send(formdata);
}
我称之为slike.php。并且它工作得很好,但是在responseText上,它并不好,有时只从循环中获取最后一个文件,有时会获得两个文件(具有相同的文本)。我不知道怎么解决这个问题,我到处寻找,但找不到答案。
I'm calling this slike.php. And it work very well, but on responseText, it's not good, sometimes get only last file from loop, sometimes get two file(with same text). I don't know how ti fix it, i was looking everywhere, and can't found the answer.
推荐答案
XHR是默认是异步的,所以除非你另外指定(在XHR open()
方法中async = false),你的循环可能在第一个XHR初始化之前就已经完成。
XHR are asynchronous by default, so unless you specify otherwise (async = false in XHR open()
method), your loop may have finished before the first XHR may have been initialized.
但代码中的 i
( this.files [i]
)在循环中引用循环的相同 i
,因此可以为 i
分配<$ c $当第一个XHR开始时,c> this.files.length-1 。 Taht是你总是得到最后一个文件的原因。
But the i
in your code (this.files[i]
) in the loop refers to the same i
of your loop, so i
may be assigned this.files.length-1
when the first XHR begins. Taht is why you always get only the last file.
这就是你必须创建所谓的闭包以确保索引的原因你正在使用的是你真正想要使用的那个。
That is why you have to create what is called a closure to make sure the index you are using is the one you really want to use.
试试这个:
for (var i = 0; i < this.files.length; i++) {
(function(index, files) { // In this closure : parameters of a function in JS
// are available only in the function,
// and cannot be changed from outside of it
var xhr = new XMLHttpRequest(); // variables declared in a function in JS
// are available only inside the function
// and cannot be changed from outside of it
xhr.upload.onprogress = function (e) {
};
xhr.onreadystatechange = function (e) {
if (this.readyState === 4) {
console.log(xhr.responseText);
}
};
var formdata = new FormData();
formdata.append("files", files[index]); // `index` has nothing to do with `i`, now:
// if `i` changes outside of the function,
//`index` will not
console.log(files[index]); // Don't keep `console.log()` in production code ;-)
xhr.open('POST', 'slike.php');
xhr.send(formdata);
})(i, this.files)
}
或者如果愿意的话想要按顺序真正获取文件:
Or if would want to really get the files sequentially :
var i = 0,
fileNb = this.files.length;
function getNextFile(file) {
var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function (e) {
};
xhr.onreadystatechange = function (e) {
if (this.readyState === 4) {
console.log(xhr.responseText);
if (++i < fileNb) getNextFile(this.files[i]);
}
};
var formdata = new FormData();
formdata.append("files", file);
console.log(file); // Don't keep `console.log()` in production code ;-)
xhr.open('POST', 'slike.php');
xhr.send(formdata);
}
getNextFile(i);
这篇关于xhr响应,for循环不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!