控制 FileReader 结果的顺序
Control the order of FileReader results
我的应用程序可以创建所选图像的预览,将它们放入 table 单元格中,并让我在上传前在同一行的其他单元格中填写每张图像的必要信息(名称、标签、来源)。但是有一个问题:我使用 FileReader
和他的异步函数 readAsDataURL
。这意味着我收到的预览顺序错误,上传后它们与照片的其他信息不匹配。在这里你可以看到结果
screenshot.
我发现了一些关于此问题的 ideas,但我不知道如何在我的案例中实现它们,当我将每个预览放在分隔的 table 单元格中并动态创建这些单元格时。
编辑:文件上传到服务器的顺序是正确的。不正确的只是我在上传之前收到的预览顺序。我的意思是,如果我的光盘上有文件 1、2、3,我可以按 3、1、2 的顺序接收预览。但是文件将作为 1、2、3 上传到服务器。
这是我的函数:
var newElem = document.createElement('table');
newElem.id = 'tl';
newElem.align = 'center';
newElem.border = 0;
for (var i = 0; i < countFiles; i++) {
var reader = new FileReader();
reader.onload = function (e) {
//create cells for each field
var newRow = newElem.insertRow(0);
var newCell1 = newRow.insertCell(0);
newCell1.innerHTML = "<input type='text' class='form-control' " +
"placeholder='Source' name='source' style='margin: 15px'>";
var newCell2 = newRow.insertCell(0);
newCell2.innerHTML = "<input type='text' class='form-control' " +
"placeholder='Tags' name='tags' style='margin: 10px'>";
var newCell3 = newRow.insertCell(0);
newCell3.innerHTML = "<input type='text' class='form-control' " +
"placeholder='Name' name='name' style='margin-left: 5px'>";
var newCell4 = newRow.insertCell(0);
//append the preview
$("<img />", {
"src": e.target.result,
"class": "thumb-image"
}).appendTo(newCell4);
};
document.getElementById("image-holder").appendChild(newElem);
reader.readAsDataURL($(this)[0].files[i]);
image_holder.show();
}
您可以将 i
传递给 IIFE。不确定 this
预期在 $(this)[0].files[i]
处是什么,尽管该元素也可以作为参数传递给 IIFE
for (var i = 0; i < countFiles; i++) {
(function readFiles(n) { // `i` : `n`
var reader = new FileReader();
reader.onload = function(e) {
//create cells for each field
var newRow = newElem.insertRow(0);
var newCell1 = newRow.insertCell(0);
newCell1.innerHTML = "<input type='text' class='form-control' " +
"placeholder='Source' name='source' style='margin: 15px'>";
var newCell2 = newRow.insertCell(0);
newCell2.innerHTML = "<input type='text' class='form-control' " +
"placeholder='Tags' name='tags' style='margin: 10px'>";
var newCell3 = newRow.insertCell(0);
newCell3.innerHTML = "<input type='text' class='form-control' " +
"placeholder='Name' name='name' style='margin-left: 5px'>";
var newCell4 = newRow.insertCell(0);
//append the preview
$("<img />", {
"src": e.target.result,
"class": "thumb-image"
}).appendTo(newCell4);
};
document.getElementById("image-holder").appendChild(newElem);
reader.readAsDataURL($(this)[0].files[n]);
image_holder.show();
}(i))
}
我找到了解决方案。用异步代码解决此类问题的好作品Promise.
这是完整的工作代码:
$(document).ready(function () {
$("#fileUpload").on('change', function () {
//get count of selected files
var countFiles = $(this)[0].files.length;
var imgPath = $(this)[0].value;
var extn = imgPath.substring(imgPath.lastIndexOf('.') + 1).toLowerCase();
var image_holder = $("#image-holder");
image_holder.empty();
if (extn == "gif" || extn == "png" || extn == "jpg" || extn == "jpeg") {
if (typeof(FileReader) != "undefined") {
//create the table
var newElem = document.createElement('table');
newElem.id = 'tl';
newElem.align = 'center';
newElem.border = 0;
//load all files using Promise
function loadImage(image) {
return new Promise(function (resolve, reject) {
var fileReader = new FileReader();
fileReader.onload = function (e) {
resolve(e.target.result);
};
fileReader.readAsDataURL(image);
});
}
//put loaded files into the queue
var queue = Promise.resolve();
[].reduceRight.call(this.files, function (queue, file, index) {
return queue.then(function () {
return loadImage(file).then(function (imageAsDataUrl) {
//attach rows with cells to the table
var newRow = newElem.insertRow(0);
var newCell1 = newRow.insertCell(0);
newCell1.innerHTML = "<input type='text' class='form-control' " +
"placeholder='Source' name='source' style='margin: 15px'>";
var newCell2 = newRow.insertCell(0);
newCell2.innerHTML = "<input type='text' class='form-control' " +
"placeholder='Tags' name='tags' style='margin: 10px'>";
var newCell3 = newRow.insertCell(0);
newCell3.innerHTML = "<input type='text' class='form-control' " +
"placeholder='Name' name='name' style='margin-left: 5px'>";
var newCell4 = newRow.insertCell(0);
$("<img />", {
"src": imageAsDataUrl,
"class": "thumb-image"
}).appendTo(newCell4);
});
});
}, Promise.resolve()).then(function () {
//everything is ready, we can attach the table to imageholder and show it
document.getElementById("image-holder").appendChild(newElem);
image_holder.show();
});
} else {
alert("This browser does not support FileReader.");
}
} else {
alert("Please select images only");
}
});
});
我的应用程序可以创建所选图像的预览,将它们放入 table 单元格中,并让我在上传前在同一行的其他单元格中填写每张图像的必要信息(名称、标签、来源)。但是有一个问题:我使用 FileReader
和他的异步函数 readAsDataURL
。这意味着我收到的预览顺序错误,上传后它们与照片的其他信息不匹配。在这里你可以看到结果
screenshot.
我发现了一些关于此问题的 ideas,但我不知道如何在我的案例中实现它们,当我将每个预览放在分隔的 table 单元格中并动态创建这些单元格时。
编辑:文件上传到服务器的顺序是正确的。不正确的只是我在上传之前收到的预览顺序。我的意思是,如果我的光盘上有文件 1、2、3,我可以按 3、1、2 的顺序接收预览。但是文件将作为 1、2、3 上传到服务器。
这是我的函数:
var newElem = document.createElement('table');
newElem.id = 'tl';
newElem.align = 'center';
newElem.border = 0;
for (var i = 0; i < countFiles; i++) {
var reader = new FileReader();
reader.onload = function (e) {
//create cells for each field
var newRow = newElem.insertRow(0);
var newCell1 = newRow.insertCell(0);
newCell1.innerHTML = "<input type='text' class='form-control' " +
"placeholder='Source' name='source' style='margin: 15px'>";
var newCell2 = newRow.insertCell(0);
newCell2.innerHTML = "<input type='text' class='form-control' " +
"placeholder='Tags' name='tags' style='margin: 10px'>";
var newCell3 = newRow.insertCell(0);
newCell3.innerHTML = "<input type='text' class='form-control' " +
"placeholder='Name' name='name' style='margin-left: 5px'>";
var newCell4 = newRow.insertCell(0);
//append the preview
$("<img />", {
"src": e.target.result,
"class": "thumb-image"
}).appendTo(newCell4);
};
document.getElementById("image-holder").appendChild(newElem);
reader.readAsDataURL($(this)[0].files[i]);
image_holder.show();
}
您可以将 i
传递给 IIFE。不确定 this
预期在 $(this)[0].files[i]
处是什么,尽管该元素也可以作为参数传递给 IIFE
for (var i = 0; i < countFiles; i++) {
(function readFiles(n) { // `i` : `n`
var reader = new FileReader();
reader.onload = function(e) {
//create cells for each field
var newRow = newElem.insertRow(0);
var newCell1 = newRow.insertCell(0);
newCell1.innerHTML = "<input type='text' class='form-control' " +
"placeholder='Source' name='source' style='margin: 15px'>";
var newCell2 = newRow.insertCell(0);
newCell2.innerHTML = "<input type='text' class='form-control' " +
"placeholder='Tags' name='tags' style='margin: 10px'>";
var newCell3 = newRow.insertCell(0);
newCell3.innerHTML = "<input type='text' class='form-control' " +
"placeholder='Name' name='name' style='margin-left: 5px'>";
var newCell4 = newRow.insertCell(0);
//append the preview
$("<img />", {
"src": e.target.result,
"class": "thumb-image"
}).appendTo(newCell4);
};
document.getElementById("image-holder").appendChild(newElem);
reader.readAsDataURL($(this)[0].files[n]);
image_holder.show();
}(i))
}
我找到了解决方案。用异步代码解决此类问题的好作品Promise.
这是完整的工作代码:
$(document).ready(function () {
$("#fileUpload").on('change', function () {
//get count of selected files
var countFiles = $(this)[0].files.length;
var imgPath = $(this)[0].value;
var extn = imgPath.substring(imgPath.lastIndexOf('.') + 1).toLowerCase();
var image_holder = $("#image-holder");
image_holder.empty();
if (extn == "gif" || extn == "png" || extn == "jpg" || extn == "jpeg") {
if (typeof(FileReader) != "undefined") {
//create the table
var newElem = document.createElement('table');
newElem.id = 'tl';
newElem.align = 'center';
newElem.border = 0;
//load all files using Promise
function loadImage(image) {
return new Promise(function (resolve, reject) {
var fileReader = new FileReader();
fileReader.onload = function (e) {
resolve(e.target.result);
};
fileReader.readAsDataURL(image);
});
}
//put loaded files into the queue
var queue = Promise.resolve();
[].reduceRight.call(this.files, function (queue, file, index) {
return queue.then(function () {
return loadImage(file).then(function (imageAsDataUrl) {
//attach rows with cells to the table
var newRow = newElem.insertRow(0);
var newCell1 = newRow.insertCell(0);
newCell1.innerHTML = "<input type='text' class='form-control' " +
"placeholder='Source' name='source' style='margin: 15px'>";
var newCell2 = newRow.insertCell(0);
newCell2.innerHTML = "<input type='text' class='form-control' " +
"placeholder='Tags' name='tags' style='margin: 10px'>";
var newCell3 = newRow.insertCell(0);
newCell3.innerHTML = "<input type='text' class='form-control' " +
"placeholder='Name' name='name' style='margin-left: 5px'>";
var newCell4 = newRow.insertCell(0);
$("<img />", {
"src": imageAsDataUrl,
"class": "thumb-image"
}).appendTo(newCell4);
});
});
}, Promise.resolve()).then(function () {
//everything is ready, we can attach the table to imageholder and show it
document.getElementById("image-holder").appendChild(newElem);
image_holder.show();
});
} else {
alert("This browser does not support FileReader.");
}
} else {
alert("Please select images only");
}
});
});