假设如下:
- 循环访问一组
img
标签 - 获取每个标签的
src
url - 使用
HTML 5
canvas
将其转换为base64
编码字符串 - 一旦所有图像都已转换,则应解决 Promise 并调用回调
我的问题:
- 我需要等待每个图像加载到
canvas
中,然后才能将其转换为base64
- 为了解决这个问题,我使用了 `img.onload = function(){ ..... return base64Img; };
- 不幸的是,每次调用
img.src = element.src;
都会解决 promise ,它不会等待图像加载并调用return base64Img;
因此,当调用$.when.apply($, Promise).then(function(){});
时,我最终得到一个空数组。
如何更改此 promise ,以便在加载和转换所有图像之前它不会解析?
function accountCreation(){
$('#container').hide(); // hide the display while we save the info as it will take a few seconds, you should do a loading bar or something here instead
var user = Parse.User.current(); // get the currently logged in user object
// loop through each image element
var promises = $('.images').map(function(index, element) {
var src = $(element).attr('src');
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var img = new Image;
img.crossOrigin = 'Anonymous';
img.onload = function(){
canvas.height = img.height;
canvas.width = img.width;
ctx.drawImage(img,0,0);
var base64Img = canvas.toDataURL('image/png');
// Clean up
canvas = null;
return base64Img;
};
img.src = element.src;
});
$.when.apply($, promises).then(function() {
// arguments[0][0] is first result
// arguments[1][0] is second result and so on
for (var i = 0; i < arguments.length; i++) {
var file = new Parse.File("photo.jpg", { base64: arguments[i]}); // this part actually saves the image file to parse
user.set("image" + i, file); // set this image to the corosponding column on our object
}
// save the user object
user.save(null,{
success: function(user) {
$('#message').html('Profile Updated!');
$('#container').show(); // show the screen again, you should just remove your loading bar now if you used one
},
error: function(user, error) {
console.log('Failed to create new object, with error code: ' + error.message);
}
});
});
}
最佳答案
您的 promise 数组仅包含未定义的值,因为回调函数不返回任何内容。由于数组中没有 Deferred
对象,因此 when
方法无需等待任何内容,因此它会正确运行 then
回调离开。
创建一个要返回的Deferred
对象,并在加载图像时解析它:
var promises = $('.images').map(function(index, element) {
// created a Deferred object to return
var deferred = $.Deferred();
var src = $(element).attr('src');
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var img = new Image;
img.crossOrigin = 'Anonymous';
img.onload = function(){
canvas.height = img.height;
canvas.width = img.width;
ctx.drawImage(img,0,0);
var base64Img = canvas.toDataURL('image/png');
// Clean up
canvas = null;
// Resolve the Deferred object when image is ready
deferred.resolve(base64Img);
};
img.src = element.src;
// return the Deferred object so that it ends up in the array
return deferred;
});
关于javascript - 在图像加载之前不要解决 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28909557/