我使用each()
循环将多个canvas元素转换为blob,然后使用AJAX将其发送到服务器。
我遇到了一个相当奇怪的问题,就是即使toBlob()
似乎仍然很忙,我的脚本的其余部分仍会继续执行。
// Empty array for blobs
var blobs = [];
// Loop through cropped images
myImages.each( function() {
var thisImage = $(this);
// Make canvas object from image
thisImage.cropper('getCroppedCanvas', {
'width': parseInt(thisImage.attr('data-width')),
'height': parseInt(thisImage.attr('data-height'))
// Create blob
}).toBlob( function(blob) {
// Add blob to blobs array
blobs.push(blob);
}, 'image/jpeg', 0.75);
});
console.log(blobs.length); // Returns 0
if ( blobs.length > 0 ) {
console.log(blobs) // Does not execute because blobs has a length of 0
}
奇怪的是,当我在
setTimeout
语句周围添加if
时,它确实执行了。setTimeout( function() {
console.log(blobs.length); // Returns 2
if ( blobs.length > 0 ) {
console.log(blobs); // Does execute
}
}, 5000);
在尝试使用AJAX将它们发送到服务器之前,如何确保toBlob函数已完成对它们的处理?
最佳答案
这是使用promises的不错选择,尤其是Promise.all
:
// Map the array of images to an array of promises
var promises = $.map(myImages, function(img) {
return new Promise(function (resolve) {
var thisImage = $(img);
// Make canvas object from image
thisImage.cropper('getCroppedCanvas', {
'width': parseInt(thisImage.attr('data-width')),
'height': parseInt(thisImage.attr('data-height'))
// Create blob
// and when called back, resolve the promise with the blob value
}).toBlob(resolve, 'image/jpeg', 0.75);
});
});
// When all promises have resolved, use the resulting array of blobs:
Promise.all(promises, function (blobs) {
console.log(blobs);
});