我使用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);
});

07-23 08:08