使用 FileReader API

问题描述

这是我关于 StackOverflow 的第一个问题 :) 我正在为个人项目学习 Javascript,但在异步函数方面遇到了一些麻烦。对于这样的功能,我还不清楚:(。 我尝试以 HTML 形式上传文件以准备 XHR 请求。下面是我在提交按钮上使用 AddEventListener 触发的函数。 我找到了关于 MDN 学习 Web 开发的说明,但由于它仅用于一个文件,因此我在 formCell[5].files(声明为全局常量)上使用 for 循环自定义它,这是我的文件所在的位置。 问题似乎出在异步行为上。堆栈方面的专家对我有什么建议吗?例如,有没有承诺的解决方案?使用 SetTimeOut 等待循环执行的“If”在我看来并不是很漂亮。 我想我尝试了数百个解决方案但没有成功:)

非常感谢, 问候, 罗曼

function sendData() {
    /* Loading files */
    var binnaryFiles = [null];

    for (let i = 0; i < formCell[5].files.length; i++) {
        let reader = new FileReader(); // FileReader API
        reader.addEventListener("load",function () { // Asynchronous function (return result when read)
            binnaryFiles[i] = reader.result;
        });
        // Read the file
        reader.readAsBinaryString(formCell[5].files[i]);
    }

    if(binnaryFiles.length !== formCell[5].files.length) {
        setTimeout( sendData,10 );
        return;
    }
    
    console.log("final" + binnaryFiles.length);

    const XHR = new XMLHttpRequest();
    const boundary = "blob"; // We need a separator to define each part of the request
    let msg = "";

    /* Loading files in the request */
    for (let i = 0; i < formCell[5].files.length; i++) {
        msg += "--" + boundary + "\r\n";
        msg += 'content-disposition: form-data; '
            + 'name="'         + formCell[5].name          + '"; '
            + 'filename="'     + formCell[5].files[i].name + '"\r\n';
        msg += 'Content-Type: ' + formCell[5].files[i].type + '\r\n';
        msg += '\r\n';
        msg += binnaryFiles[i] + '\r\n';
    }

    /* Loading texts in the request */
    for (let i = 0; i < formCell.length - 1; i++) {
        msg += "--" + boundary + "\r\n";
        msg += 'content-disposition: form-data; name="' + formCell[i].name + '"\r\n';
        msg += '\r\n';
        msg += formCell[i].value + "\r\n";
    }

    msg += "--" + boundary + "--";

    XHR.addEventListener("load",function(event) {
        alert( 'Yeah! Data sent and response loaded.' );
    });
    XHR.addEventListener("error",function(event) {
        alert("Oops! Something went wrong.");
    } );
    XHR.open("POST","http://localhost:3000/upload");
    XHR.setRequestHeader("Content-Type","multipart/form-data; boundary=" + boundary);
    XHR.send(msg);
    console.log(msg);
}

解决方法

我想我已经使用 Promises 解决了我的问题:) 如果有人可以确认我下面的代码是正确的,它可以帮助我:)

谢谢, 罗曼

function fileUpLoad(fileToUpload) {
    return new Promise((resolve,reject) => {
        const reader = new FileReader(); // FileReader API
        
        reader.addEventListener("load",function () { // Asynchronous function (return result when read)
            resolve(reader.result);
            reject(reader.error);
        });
        // Read the file
        reader.readAsBinaryString(fileToUpload);
    });
}

/* Sending message */
function sendData(filesUploaded) {
    let binnaryFiles = filesUploaded;

    const XHR = new XMLHttpRequest();
    const boundary = "blob"; // We need a separator to define each part of the request
    let msg = "";

    /* Loading files in the request */
    for (let i = 0; i < binnaryFiles.length; i++) {
        msg += "--" + boundary + "\r\n";
        msg += 'content-disposition: form-data; '
            + 'name="'         + formCell[5].name          + '"; '
            + 'filename="'     + formCell[5].files[i].name + '"\r\n';
        msg += 'Content-Type: ' + formCell[5].files[i].type + '\r\n';
        msg += '\r\n';
        msg += binnaryFiles[i] + '\r\n';
    }

    /* Loading texts in the request */
    for (let i = 0; i < formCell.length - 1; i++) {
        msg += "--" + boundary + "\r\n";
        msg += 'content-disposition: form-data; name="' + formCell[i].name + '"\r\n';
        msg += '\r\n';
        msg += formCell[i].value + "\r\n";
    }

    msg += "--" + boundary + "--";

    XHR.addEventListener("load",function(event) {
        alert( 'Yeah! Data sent and response loaded.' );
    });
    XHR.addEventListener("error",function(event) {
        alert("Oops! Something went wrong.");
    } );
    XHR.open("POST","http://localhost:3000/upload");
    XHR.setRequestHeader("Content-Type","multipart/form-data; boundary=" + boundary);
    XHR.send(msg);
    console.log(msg);
}

        /* Validation on submit calling */
        form.addEventListener("submit",function (evt) {
            evt.preventDefault();
            if (validationOnSubmit()) {
                if (formCell[5].files.length > 0) {
                    let fileUploadingPromise = []
                    for (let i = 0; i < formCell[5].files.length; i++) {
                        fileUploadingPromise[i] = fileUpLoad(formCell[5].files[i]);
                    }
                    let binnaryFiles = [null];
                    Promise.all(fileUploadingPromise)
                        .then (resolve => {
                            for (let i = 0; i < formCell[5].files.length; i++) {
                                binnaryFiles[i] = resolve[i];
                            }
                            sendData(binnaryFiles)
                        })
                        .catch (reject => {
                            console.log(reject);
                        });
                } else {
                    sendData(0);
                }
            }
        });

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...