Javascript -异步函数导致不正确的顺序
Javascript - Async functions causing incorrect order
我正在用Javascript构建一个照片上传器,为了读取已经上传的照片,我有以下代码:
// Populate with existing photos
var index;
for (index = 0; index < params.photosToPopulate.length; ++index) {
// Get the data of the image
getDataUri(params.photosToPopulate[index], params, function(dataURI){
// Get the Blob
dataURItoBlob(dataURI, function(dataurl){
var blob = URL.createObjectURL(dataurl);
// fileItem
var fileItem = document.createElement("div");
fileItem.setAttribute('angle', 0);
fileItem.setAttribute('blob', blob);
fileItem.className = 'imageloaderplusFile';
filesdiv.appendChild(fileItem);
// fileImg
var fileImg = document.createElement("div");
fileImg.className = 'imageloaderplusImage';
fileImg.style.backgroundImage = 'url(' + dataURI + ')';
fileItem.appendChild(fileImg);
// fileRotate
var fileRotate = document.createElement("div");
fileRotate.className = 'imageloaderRotate';
fileRotate.setAttribute('title', 'Rotate');
fileItem.appendChild(fileRotate);
fileRotate.onclick = function(){
var angle;
switch(parseInt(this.parentNode.getAttribute('angle'))){
case 0:
angle = 90;
break;
case 90:
angle = 180;
break;
case 180:
angle = 270;
break;
case 270:
angle = 0;
break;
}
this.parentNode.setAttribute('angle', angle);
// css
var image = this.parentNode.firstChild;
image.style.webkitTransform = 'rotate(' + angle + 'deg)';
image.style.mozTransform = 'rotate(' + angle + 'deg)';
image.style.msTransform = 'rotate(' + angle + 'deg)';
image.style.oTransform = 'rotate(' + angle + 'deg)';
image.style.transform = 'rotate(' + angle + 'deg)';
// draw
ImageLoaderPlus.draw(this.parentNode, params);
}
// fileRemove
var fileRemove = document.createElement("div");
fileRemove.className = 'imageloaderRemove';
fileRemove.setAttribute('title', 'Remove');
fileItem.appendChild(fileRemove);
fileRemove.onclick = function(){
this.parentNode.parentNode.removeChild(this.parentNode);
}
// draw
ImageLoaderPlus.draw(fileItem, params);
});
});
} // End For Loop
在For循环中,我有有序的照片,但有时由于异步函数getDataUri()和dataURItoBlob(), For循环中项目的顺序将无法转换为de UI/DOM中的顺序,并且照片以不正确的顺序显示。我怎样才能避免这种情况的发生?
异步函数是这样的:
function getDataUri(url, params, callback) {
var image = new Image();
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
//image.crossOrigin = "anonymous"; // This enables CORS
// get scale
var scale = (params.resize && (image.width > params.maxWidth || image.height > params.maxHeight)) ? Math.min(params.maxWidth / image.width, params.maxHeight / image.height) : 1;
image.onload = function (event) {
try {
canvas.width = Math.round(image.width * scale);
canvas.height = Math.round(image.height * scale);
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
//console.log( ctx.canvas.toDataURL('image/jpeg', params.jpegQuality) );
result = ctx.canvas.toDataURL('image/jpeg', params.jpegQuality)
callback(result);
} catch (e) {
alert(e);
}
};
image.src = url;
}
// To convert URL to Blob
function dataURItoBlob(dataURI, callback) {
// convert base64 to raw binary data held in a string
// doesn't handle URLEncoded DataURIs
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0) {
byteString = atob(dataURI.split(',')[1]);
} else {
byteString = unescape(dataURI.split(',')[1]);
}
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to an ArrayBuffer
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
try {
result = new Blob([ab], {type: mimeString});
//return new Blob([ab], {type: mimeString});
} catch (e) {
// The BlobBuilder API has been deprecated in favour of Blob, but older
// browsers don't know about the Blob constructor
// IE10 also supports BlobBuilder, but since the `Blob` constructor
// also works, there's no need to add `MSBlobBuilder`.
var BlobBuilder = window.WebKitBlobBuilder || window.MozBlobBuilder;
var bb = new BlobBuilder();
bb.append(ab);
result = bb.getBlob(mimeString);
//return bb.getBlob(mimeString);
}
callback(result);
}
关于如何避免这个问题有什么线索吗?
问好,
您可以通过在收到dataurl
值时将它们存储在数组中来解决这个问题,但是存储在该数组的正确索引处。然后,当您计算收到的所有dataurl
值时,您将在该数组上执行循环并执行元素创建代码,就像现在一样。
// Intermediate array to store the dataURI and dataurl values in order
var urls = [];
var URIs = [];
// Keep count of how many dataurl values we received
var leftOver = params.photosToPopulate.length;
// Iterate in a way that you create a new closure on every iteration,
// each iteration has its proper index variable
params.photosToPopulate.forEach(function (photo, index) {
// Get the data of the image
getDataUri(photo, params, function(dataURI){
// Store at the right place in our array
URIs[index] = dataURI;
// Get the Blob
dataURItoBlob(dataURI, function(dataurl){
// Only store the url at the right place in our array
urls[index] = dataurl;
// ... and update the count
leftOver--;
// All done? Then iterate over the dataurl values in the correct order
if (!leftOver) urls.forEach(function(dataurl, index) {
var dataURI = URIs[index]; // get correct dataURI
var blob = URL.createObjectURL(dataurl);
// fileItem
var fileItem = document.createElement("div");
// ...etc, all your element creation code comes here, unchanged.
// ...
// draw
ImageLoaderPlus.draw(fileItem, params);
});
});
});
});
相关文章:
- Jquery菜单操作不稳定,定位不正确,存在一般错误
- Amazon S3 REST API大小不正确
- Javascript Reg Exp不正确匹配
- DIV并排,位置不正确
- 仅在IE中,javascript中的时区名称不正确
- 注意:wp_enqueue_script调用不正确.在 Wordpress 调试模式下
- Node.js:多个然后'It’执行顺序不正确
- 画布绘制调用呈现顺序不正确
- JavaScript 循环输出顺序不正确 - 如何解决这个问题
- 在 sort() 之后,十进制数的 JavaScript 数组顺序不正确
- 阅读顺序不正确
- AngularJS异步调用多个数据库,并且保存顺序不正确
- 以不正确的顺序从绑定中删除2.0参数
- 函数的执行顺序不正确
- 引导旋转木马指示不按正确顺序循环
- 为什么浏览器不一致地呈现顺序不正确的jQuery
- Javascript -异步函数导致不正确的顺序
- Jquery .fadein .fadeout回调嵌套顺序不正确
- 对顺序不正确的数字进行排序
- Jquery滑块需要javascript帮助,缩略图的顺序不正确