我正在做一个项目,我需要一个表单。我想通过 AJAX 将数据发送到后端。我有一个文件上传,我需要将文件转换为base64,这样我就可以将其保存到我的数据库中。我使用FileReader在jQuery中转换文件。问题是,即使我添加了Promise()和await/async,我的 AJAX 函数也会在文件转换之前执行。我知道我做错了什么,但我不明白是什么。
有人能帮忙吗,我弄不好。谢谢!
这是我在控制台中得到的。你可以看到,文件在 AJAX 函数之后被记录,并且文件元素不在发送到后端的数据日志中。x1c 0d1x
我的ajax.js文件
$(document).ready(function () {
$("form").submit(async function (e) {
e.preventDefault();
var children = $(this).find("input, textarea");
console.log($(children).length);
var nodeId = $(this).attr("data-nodeId");
await loopChildren(children).then((allData) => ajaxCall(allData, nodeId))
})
});
function loopChildren(children) {
return new Promise((resolve) => {
var allData = [];
$(children).each(async function (index, elem) {
var dataType = getDataType($(elem).attr("type"));
await getContent(elem).then(function (content) {
console.log("content " + index + " :" + content);
allData.push({ "nodeId": parseInt($(elem).attr("id")), "content": content, "dataType": dataType });
});
})
resolve(allData);
})
}
function getContent(elem) {
return new Promise(async (resolve) => {
if ($(elem).attr("type") == "checkbox" || $(elem).attr("type") == "radio") {
resolve($(elem).is(":checked"));
}
else if ($(elem).attr("type") == "file") {
for (var file of $(elem)[0].files) {
await processFile(file).then(function (e) {
resolve(e)
});
}
}
else {
resolve($(elem).val());
}
})
}
function readFileAsync(file) {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.onload = () => {
resolve(reader.result);
};
reader.onerror = reject;
reader.readAsDataURL(file);
})
}
function processFile(file) {
return new Promise(async (resolve, reject) => {
try {
await readFileAsync(file).then(function(content) {
console.log(content);
resolve(content);
});
} catch (err) {
console.log(err);
reject(err);
}
})
}
function ajaxCall(myVeryOwnDataObject, nodeID) {
console.log(JSON.stringify(myVeryOwnDataObject));
$.ajax({
type: "POST",
url: "/Umbraco/Api/Form/SendForm",
contentType: "application/json; charset=utf-8",
headers: { 'nodeId': nodeID },
data: JSON.stringify(myVeryOwnDataObject),
success: function (success) {
console.log(success);
},
error: function (error) {
console.log(error);
}
})
}
function getDataType(element) {
switch (element) {
case "text":
return "text"
break;
case "textarea":
return "textarea"
break;
case "number":
return "number"
break;
case "email":
return "text"
break;
case "tel":
return "text"
break;
case "url":
return "text"
break;
case "color":
return "text"
break;
case "range":
return "number"
break;
case "date":
return "date"
break;
case "datetime-local":
return "dateTime"
break;
case "month":
return "date"
break;
case "time":
return "time"
break;
case "file":
return "file"
break;
case "checkbox":
return "check"
break;
case "radio":
return "check"
break;
}
}
1条答案
按热度按时间cqoc49vn1#
loopChildren
函数存在问题。尽管在
getContent
调用之前有一个await
,但这个承诺基本上被放弃了,因为在创建它的异步函数上没有任何await
。此函数的执行方式为:
allData
的变量children
中的每个元素,并为每个元素创建一个异步函数allData
的值解析Promise,该值是空数组,因为我们没有对.each
循环的结果执行await
为了解决这个问题,我将使用
.map
而不是.each
,以便将children
的每个元素Map到一个Promise中。然后我将使用Promise.all等待 * 所有 * 这些Promise的解析。我们可以直接从loopChildren
返回Promise.all
,并删除new Promise
。函数变为:
我创建了一个fiddle,它模拟了Promise解决方案的流程。