问题描述
这是我关于 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);
}
}
});