在图像加载之前不要解决承诺
Dont resolve promise until after images load
下面是假设:
- 遍历一组
img
个标签
- 抓取每个标签的
src
url
- 使用
HTML 5
canvas
将其转换为 base64
编码字符串
- 一旦所有图像都已转换,应解决承诺并调用回调
我的问题:
- 我需要等待每个图像加载到
canvas
才能将其转换为 base64
- 为了解决这个问题,我使用了`img.onload = function(){ ..... return base64Img; };
- 不幸的是,每次调用
img.src = element.src;
都会解决承诺,它不会等待图像加载并调用 return base64Img;
所以当 $.when.apply($, promises).then(function(){});
被调用。
如何更改此承诺,使其在加载和转换所有图像之前不解析?
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);
}
});
});
}
您的承诺数组只包含未定义的值,因为回调函数 return 没有任何内容。由于数组中没有 Deferred
对象,when
方法没有任何等待,因此它立即运行 then
回调。
创建一个Deferred
对象到return,并在加载图像时解决它:
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;
});
下面是假设:
- 遍历一组
img
个标签 - 抓取每个标签的
src
url - 使用
HTML 5
canvas
将其转换为 - 一旦所有图像都已转换,应解决承诺并调用回调
base64
编码字符串
我的问题:
- 我需要等待每个图像加载到
canvas
才能将其转换为base64
- 为了解决这个问题,我使用了`img.onload = function(){ ..... return base64Img; };
- 不幸的是,每次调用
img.src = element.src;
都会解决承诺,它不会等待图像加载并调用return base64Img;
所以当$.when.apply($, promises).then(function(){});
被调用。
如何更改此承诺,使其在加载和转换所有图像之前不解析?
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);
}
});
});
}
您的承诺数组只包含未定义的值,因为回调函数 return 没有任何内容。由于数组中没有 Deferred
对象,when
方法没有任何等待,因此它立即运行 then
回调。
创建一个Deferred
对象到return,并在加载图像时解决它:
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;
});