javascript - for 循环的 xhr 响应不起作用

标签 javascript jquery file upload xmlhttprequest

我有带有 for 循环的 xhr,但它很少工作

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上,它不好,有时只从循环中获取最后一个文件,有时得到两个文件(具有相同的文本)。我不知道如何解决它,我到处寻找,但找不到答案。

最佳答案

XHR 默认情况下是异步的,因此除非您另外指定(XHR open() 方法中的 async = false),您的循环可能会在第一个 XHR 初始化之前完成。

但是循环中代码 (this.files[i]) 中的 i 引用循环中相同的 i,因此,当第一个 XHR 开始时,i 可能会被分配到 this.files.length-1。这就是为什么你总是只得到最后一个文件。

这就是为什么您必须创建所谓的闭包以确保您正在使用的索引是您真正想要使用的索引。

试试这个:

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)
}

或者如果想真正按顺序获取文件:

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);

关于javascript - for 循环的 xhr 响应不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26100329/

相关文章:

java - 将文件传递给另一个方法时出现矛盾的异常

javascript - 了解 Suspense 和 React Hooks

javascript - 不使用max-height的过渡高度

javascript - jquery加载div属性返回未定义

javascript - 下拉菜单对齐问题

python - 读取文件的多种方式?

Python:如果找不到文件,请尝试查找不同的文件名

javascript - 访问VueJS中根组件的prop

javascript - 在哪里删除 forEach 循环/函数中的 null 元素?

javascript - 删除 div 折叠上的链接文本?